diff options
Diffstat (limited to 'lib/hc32f460/driver/src')
41 files changed, 38027 insertions, 0 deletions
diff --git a/lib/hc32f460/driver/src/hc32f460_adc.c b/lib/hc32f460/driver/src/hc32f460_adc.c new file mode 100644 index 00000000..08f406bb --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_adc.c @@ -0,0 +1,1742 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_adc.c
+ **
+ ** A detailed description is available at
+ ** @link AdcGroup Adc description @endlink
+ **
+ ** - 2018-11-30 CDT First version for Device Driver Library of Adc.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_adc.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup AdcGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*! Parameter validity check for ADC peripherals. */
+#define IS_ADC_PERIPH(ADCx) \
+( ((ADCx) == M4_ADC1) || \
+ ((ADCx) == M4_ADC2))
+
+/*! Parameter validity check for ADC1 channel index. */
+#define IS_ADC1_CH_INDEX(x) \
+( ((x) < ADC1_CH_COUNT))
+
+/*! Parameter validity check for ADC2 channel index. */
+#define IS_ADC2_CH_INDEX(x) \
+( ((x) < ADC2_CH_COUNT))
+
+/*! Parameter validity check for ADC average count. */
+#define IS_ADC_AVCNT(AVCNT) \
+( ((AVCNT) == AdcAvcnt_2) || \
+ (((AVCNT) >= AdcAvcnt_4) && ((AVCNT) <= AdcAvcnt_256)))
+
+/*! Parameter validity check for ADC data alignment. */
+#define IS_ADC_DATA_ALIGN(ALIGN) \
+( ((ALIGN) == AdcDataAlign_Right) || \
+ ((ALIGN) == AdcDataAlign_Left))
+
+/*! Parameter validity check for ADC auto clear DR. */
+#define IS_ADC_CLREN(EN) \
+( ((EN) == AdcClren_Enable) || \
+ ((EN) == AdcClren_Disable))
+
+/*! Parameter validity check for ADC resolution. */
+#define IS_ADC_RESOLUTION(RESOLUTION) \
+( ((RESOLUTION) == AdcResolution_8Bit) || \
+ ((RESOLUTION) == AdcResolution_10Bit) || \
+ ((RESOLUTION) == AdcResolution_12Bit))
+
+/*! Parameter validity check for ADC scan convert mode. */
+#define IS_ADC_SCAN_MODE(MODE) \
+( ((MODE) == AdcMode_SAOnce) || \
+ ((MODE) == AdcMode_SAContinuous) || \
+ ((MODE) == AdcMode_SAOnceSBOnce) || \
+ ((MODE) == AdcMode_SAContinuousSBOnce))
+
+/*! Parameter validity check for ADC RSCHSEL. */
+#define IS_ADC_RSCHSEL(SEL) \
+( ((SEL) == AdcRschsel_Continue) || \
+ ((SEL) == AdcRschsel_Restart))
+
+/*! Parameter validity check for ADC SA trigger source. */
+#define IS_ADC_TRGEN(EN) \
+( ((EN) == AdcTrgen_Enable) || \
+ ((EN) == AdcTrgen_Disable))
+
+/*! Parameter validity check for ADC SA trigger source. */
+#define IS_ADC_TRGSEL(SEL) \
+( ((SEL) == AdcTrgsel_ADTRGX) || \
+ ((SEL) == AdcTrgsel_TRGX0) || \
+ ((SEL) == AdcTrgsel_TRGX1) || \
+ ((SEL) == AdcTrgsel_TRGX0_TRGX1))
+
+/*! Parameter validity check for ADC common trigger. */
+#define IS_ADC_COM_TRIGGER(x) \
+( ((x) == AdcComTrigger_1) || \
+ ((x) == AdcComTrigger_2) || \
+ ((x) == AdcComTrigger_1_2))
+
+/*! Parameter validity check for ADC EOCAIEN/ENCBIEN. */
+#define IS_ADC_EOCIEN(EN) \
+( ((EN) == AdcEocien_Disable) || \
+ ((EN) == AdcEocien_Enable))
+
+/*! Parameter validity check for ADC sampling time. */
+#define IS_ADC_SAMPLE_TIME(TIME) \
+( ((TIME) == 255u) || \
+ (((TIME) >= 5u) && ((TIME) <= 254u)))
+
+/*! Parameter validity check for ADC sync trigger mode. */
+#define IS_ADC_SYNC_MODE(MODE) \
+( ((MODE) == AdcSync_SingleSerial) || \
+ ((MODE) == AdcSync_SingleParallel) || \
+ ((MODE) == AdcSync_ContinuousSerial) || \
+ ((MODE) == AdcSync_ContinuousParallel))
+
+/*! Parameter validity check for ADC sync able. */
+#define IS_ADC_SYNC_ENABLE(EN) \
+( ((EN) == AdcSync_Disable) || \
+ ((EN) == AdcSync_Enable))
+
+/*! Parameter validity check for ADC ADWIEN */
+#define IS_ADC_AWDIEN(EN) \
+( ((EN) == AdcAwdInt_Disable) || \
+ ((EN) == AdcAwdInt_Enable))
+
+/*! Parameter validity check for ADC AWDSS */
+#define IS_ADC_AWDSS(SS) \
+( ((SS) == AdcAwdSel_SA_SB) || \
+ ((SS) == AdcAwdSel_SA) || \
+ ((SS) == AdcAwdSel_SB) || \
+ ((SS) == AdcAwdSel_SB_SA))
+
+/*! Parameter validity check for ADC AWDMD */
+#define IS_ADC_AWDMD(MD) \
+( ((MD) == AdcAwdCmpMode_0) || \
+ ((MD) == AdcAwdCmpMode_1))
+
+/*! Parameter validity check for ADC AWDEN */
+#define IS_ADC_AWDEN(EN) \
+( ((EN) == AdcAwd_Disable) || \
+ ((EN) == AdcAwd_Enable))
+
+/*! Parameter validity check for ADC PGA control */
+#define IS_ADC_PGA_CTL(CTL) \
+( ((CTL) == AdcPgaCtl_Invalid) || \
+ ((CTL) == AdcPgaCtl_Amplify))
+
+/*! Parameter validity check for ADC gain factor. */
+#define IS_ADC_PGA_FACTOR(FACTOR) \
+( ((FACTOR) == AdcPgaFactor_2) || \
+ (((FACTOR) >= AdcPgaFactor_2P133) && ((FACTOR) <= AdcPgaFactor_32)))
+
+/*! Parameter validity check for ADC PGA negative. */
+#define IS_ADC_PGA_NEGATIVE(N) \
+( ((N) == AdcPgaNegative_VSSA) || \
+ ((N) == AdcPgaNegative_PGAVSS))
+
+/*! Parameter validity check for ADC PGA channel. */
+#define IS_ADC_PGA_CH(ch) \
+( ((ch) == PGA_CH_NONE) || \
+ ((ch) == PGA_CH0) || \
+ ((ch) == PGA_CH1) || \
+ ((ch) == PGA_CH2) || \
+ ((ch) == PGA_CH3) || \
+ ((ch) == PGA_CH4) || \
+ ((ch) == PGA_CH5) || \
+ ((ch) == PGA_CH6) || \
+ ((ch) == PGA_CH7) || \
+ ((ch) == PGA_CH8))
+
+/*! Parameter validity check for ADC trigger source event . */
+#define IS_ADC_TRIG_SRC_EVENT(x) \
+( ((x) == EVT_PORT_EIRQ0) || \
+ (((x) > EVT_PORT_EIRQ0) && ((x) <= EVT_PORT_EIRQ15)) || \
+ (((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
+ (((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
+ (((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
+ (((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
+ (((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
+ (((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
+ (((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
+ (((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
+ (((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
+ (((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
+ (((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
+ (((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
+ (((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
+ (((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
+ (((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
+ (((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
+ (((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
+ (((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
+ (((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
+ (((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
+ (((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
+ (((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
+ (((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
+ (((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
+ (((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
+ ((x) == EVT_WDT_REFUDF) || \
+ (((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
+ (((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
+ (((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)) || \
+ ((x) == EVT_MAX))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+static void ADC_ReadAllData(const M4_ADC_TypeDef *ADCx, uint16_t *pu16AdcData, uint8_t u8Length);
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initializes an ADC instance.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] pstcInit Pointer to ADC initialization structure.
+ ** See @ref stc_adc_init_t for details.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_Init(M4_ADC_TypeDef *ADCx, const stc_adc_init_t *pstcInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((NULL != ADCx) && (NULL != pstcInit))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_ADC_RESOLUTION(pstcInit->enResolution));
+ DDL_ASSERT(IS_ADC_DATA_ALIGN(pstcInit->enDataAlign));
+ DDL_ASSERT(IS_ADC_CLREN(pstcInit->enAutoClear));
+ DDL_ASSERT(IS_ADC_SCAN_MODE(pstcInit->enScanMode));
+ DDL_ASSERT(IS_ADC_RSCHSEL(pstcInit->enRschsel));
+
+ /* Stop ADC conversion. */
+ ADCx->STR = 0u;
+
+ ADCx->CR0_f.ACCSEL = pstcInit->enResolution;
+ ADCx->CR0_f.DFMT = pstcInit->enDataAlign;
+ ADCx->CR0_f.CLREN = pstcInit->enAutoClear;
+ ADCx->CR0_f.MS = pstcInit->enScanMode;
+ ADCx->CR1_f.RSCHSEL = pstcInit->enRschsel;
+
+ /* Disable EOC(End Of Conversion) interrupts default. */
+ ADCx->ICR = (uint8_t)0x0;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Deinitializes an ADC instance.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_DeInit(M4_ADC_TypeDef *ADCx)
+{
+ uint8_t i;
+ uint8_t u8SstrNum;
+ uint32_t u32SSTRAddr;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ /* Set the value of all registers to the reset value. */
+ /* Stop ADC conversion. */
+ ADCx->STR = 0u;
+ ADCx->CR0 = 0u;
+ ADCx->CR1 = 0u;
+ ADCx->TRGSR = 0u;
+ ADCx->CHSELRA0 = 0u;
+ ADCx->CHSELRB0 = 0u;
+ ADCx->AVCHSELR0 = 0u;
+ ADCx->CHMUXR0 = (uint16_t)0x3210;
+ ADCx->CHMUXR1 = (uint16_t)0x7654;
+ ADCx->ISR = 0u;
+ ADCx->ICR = (uint8_t)0x03;
+ ADCx->AWDCR = 0u;
+ ADCx->AWDDR0 = 0u;
+ ADCx->AWDDR1 = 0u;
+ ADCx->AWDCHSR0 = 0u;
+ ADCx->AWDSR0 = 0u;
+
+ u32SSTRAddr = (uint32_t)&ADCx->SSTR0;
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->CHSELRA1 = 0u;
+ ADCx->CHSELRB1 = 0u;
+ ADCx->AVCHSELR1 = 0u;
+ ADCx->CHMUXR2 = (uint16_t)0xBA98;
+ ADCx->CHMUXR3 = (uint16_t)0xFEDC;
+ ADCx->SYNCCR = (uint16_t)0x0C00;
+ ADCx->AWDCHSR1 = 0u;
+ ADCx->AWDSR1 = 0u;
+ ADCx->PGACR = 0u;
+ ADCx->PGAGSR = 0u;
+ ADCx->PGAINSR0 = 0u;
+ ADCx->PGAINSR1 = 0u;
+ ADCx->SSTRL = 0x0Bu;
+ u8SstrNum = 16u;
+ }
+ else
+ {
+ u8SstrNum = 9u;
+ }
+
+ for (i=0u; i<u8SstrNum; i++)
+ {
+ *(__IO uint8_t *)u32SSTRAddr = 0x0Bu;
+ u32SSTRAddr++;
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set scan mode.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param[in] enMode See @ref en_adc_scan_mode_t for details.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_SetScanMode(M4_ADC_TypeDef *ADCx, en_adc_scan_mode_t enMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_ADC_SCAN_MODE(enMode));
+
+ ADCx->CR0_f.MS = enMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set trigger source.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] pstcTrgCfg Pointer to ADC trigger source configuration structure.
+ ** \arg u8Sequence The sequence which you want to set it's trigger source.
+ ** \arg enTrgEnable Enable or disable trigger source.
+ ** \arg enTrgSel The type of trigger source.
+ ** \arg enInTrg0 Event number @ref en_event_src_t.
+ ** \arg enInTrg1 Event number @ref en_event_src_t.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ ** \note Sequence A and Sequence B CAN NOT set the same trigger source.
+ **
+ ******************************************************************************/
+en_result_t ADC_ConfigTriggerSrc(M4_ADC_TypeDef *ADCx,
+ const stc_adc_trg_cfg_t *pstcTrgCfg)
+{
+ uint32_t u32TrgSelR;
+ __IO uint32_t *io32AdcxTrgSelR0;
+ __IO uint32_t *io32AdcxTrgSelR1;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((NULL != ADCx) &&
+ (NULL != pstcTrgCfg) &&
+ (pstcTrgCfg->u8Sequence <= ADC_SEQ_B))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_ADC_TRGSEL(pstcTrgCfg->enTrgSel));
+
+ if (ADC_SEQ_A == pstcTrgCfg->u8Sequence)
+ {
+ ADCx->TRGSR_f.TRGSELA = pstcTrgCfg->enTrgSel;
+ }
+ else
+ {
+ ADCx->TRGSR_f.TRGSELB = pstcTrgCfg->enTrgSel;
+ }
+
+ if (AdcTrgsel_ADTRGX != pstcTrgCfg->enTrgSel)
+ {
+ if (M4_ADC1 == ADCx)
+ {
+ io32AdcxTrgSelR0 = &(M4_AOS->ADC1_ITRGSELR0);
+ io32AdcxTrgSelR1 = &(M4_AOS->ADC1_ITRGSELR1);
+ }
+ else
+ {
+ io32AdcxTrgSelR0 = &(M4_AOS->ADC2_ITRGSELR0);
+ io32AdcxTrgSelR1 = &(M4_AOS->ADC2_ITRGSELR1);
+ }
+
+ if ((pstcTrgCfg->enTrgSel & AdcTrgsel_TRGX0) == AdcTrgsel_TRGX0)
+ {
+ DDL_ASSERT(IS_ADC_TRIG_SRC_EVENT(pstcTrgCfg->enInTrg0));
+
+ u32TrgSelR = *io32AdcxTrgSelR0;
+ u32TrgSelR &= ~0x1FFul;
+ u32TrgSelR |= pstcTrgCfg->enInTrg0;
+ *io32AdcxTrgSelR0 = u32TrgSelR;
+ }
+ if ((pstcTrgCfg->enTrgSel & AdcTrgsel_TRGX1) == AdcTrgsel_TRGX1)
+ {
+ DDL_ASSERT(IS_ADC_TRIG_SRC_EVENT(pstcTrgCfg->enInTrg1));
+
+ u32TrgSelR = *io32AdcxTrgSelR1;
+ u32TrgSelR &= ~0x1FFul;
+ u32TrgSelR |= pstcTrgCfg->enInTrg1;
+ *io32AdcxTrgSelR1 = u32TrgSelR;
+ }
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set trigger source.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u8Seq The sequence which you want to set it's trigger source.
+ **
+ ** \param [in] enState Enable or disable trigger source.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_TriggerSrcCmd(M4_ADC_TypeDef *ADCx,
+ uint8_t u8Seq,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((NULL != ADCx) && (u8Seq <= ADC_SEQ_B))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (ADC_SEQ_A == u8Seq)
+ {
+ ADCx->TRGSR_f.TRGENA = enState;
+ }
+ else
+ {
+ ADCx->TRGSR_f.TRGENB = enState;
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable ADC common trigger.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] enTrgSel ADC trigger source type. See @ref en_adc_trgsel_t for details.
+ **
+ ** \param [in] enComTrigger ADC common trigger selection. See @ref en_adc_com_trigger_t for details.
+ **
+ ** \param [in] enState Enable or disable the specified common trigger.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void ADC_ComTriggerCmd(M4_ADC_TypeDef *ADCx, en_adc_trgsel_t enTrgSel, \
+ en_adc_com_trigger_t enComTrigger, en_functional_state_t enState)
+{
+ uint32_t u32ComTrig = enComTrigger;
+ uint32_t u32ITRGSELRAddr;
+
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_ADC_TRGSEL(enTrgSel) && (enTrgSel != AdcTrgsel_ADTRGX));
+ DDL_ASSERT(IS_ADC_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (M4_ADC1 == ADCx)
+ {
+ u32ITRGSELRAddr = (uint32_t)&M4_AOS->ADC1_ITRGSELR0;
+ }
+ else
+ {
+ u32ITRGSELRAddr = (uint32_t)&M4_AOS->ADC2_ITRGSELR0;
+ }
+
+ u32ComTrig <<= 30u;
+
+ if ((enTrgSel & AdcTrgsel_TRGX0) == AdcTrgsel_TRGX0)
+ {
+ if (enState == Enable)
+ {
+ *(__IO uint32_t *)u32ITRGSELRAddr |= u32ComTrig;
+ }
+ else
+ {
+ *(__IO uint32_t *)u32ITRGSELRAddr &= ~u32ComTrig;
+ }
+ }
+
+ if ((enTrgSel & AdcTrgsel_TRGX1) == AdcTrgsel_TRGX1)
+ {
+ u32ITRGSELRAddr += 4ul;
+ if (enState == Enable)
+ {
+ *(__IO uint32_t *)u32ITRGSELRAddr |= u32ComTrig;
+ }
+ else
+ {
+ *(__IO uint32_t *)u32ITRGSELRAddr &= ~u32ComTrig;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Add ADC channel.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] pstcChCfg Pointer to ADC channel configuration structure.
+ ** \arg u32Channel The channel(s) you want to configure.
+ ** \arg u8Sequence The sequence which the channel(s) belong(s) to.
+ ** \arg pu8SampTime Pointer to sampling time.
+ ** eg. u32Channel = 1001b
+ ** pu8SampTime[0] = channel 0's time
+ ** pu8SampTime[1] = channel 3's time
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ ** \note Sequence A and Sequence B CAN NOT set the same channel!!!
+ **
+ ******************************************************************************/
+en_result_t ADC_AddAdcChannel(M4_ADC_TypeDef *ADCx, const stc_adc_ch_cfg_t *pstcChCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint8_t i;
+ uint8_t j;
+ uint32_t u32ChannelSel;
+ __IO uint8_t *io8Sstr;
+
+ if ((NULL != ADCx) &&
+ (NULL != pstcChCfg) &&
+ (pstcChCfg->u8Sequence <= ADC_SEQ_B))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (M4_ADC1 == ADCx)
+ {
+ u32ChannelSel = pstcChCfg->u32Channel & ADC1_CH_ALL;
+ if (ADC_SEQ_A == pstcChCfg->u8Sequence)
+ {
+ ADCx->CHSELRA0 |= (uint16_t)u32ChannelSel;
+ ADCx->CHSELRA1 |= (uint16_t)(u32ChannelSel >> 16u);
+ }
+ else
+ {
+ ADCx->CHSELRB0 |= (uint16_t)u32ChannelSel;
+ ADCx->CHSELRB1 |= (uint16_t)(u32ChannelSel >> 16u);
+ }
+ }
+ else
+ {
+ u32ChannelSel = pstcChCfg->u32Channel & ADC2_CH_ALL;
+ if (ADC_SEQ_A == pstcChCfg->u8Sequence)
+ {
+ ADCx->CHSELRA0 |= (uint16_t)u32ChannelSel;
+ }
+ else
+ {
+ ADCx->CHSELRB0 |= (uint16_t)u32ChannelSel;
+ }
+ }
+
+ /* Set sampling time */
+ i = 0u;
+ j = 0u;
+ io8Sstr = &(ADCx->SSTR0);
+ while (0u != u32ChannelSel)
+ {
+ if (u32ChannelSel & 0x1ul)
+ {
+ io8Sstr[i] = pstcChCfg->pu8SampTime[j++];
+ }
+ u32ChannelSel >>= 1u;
+ i++;
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Delete ADC channel(s).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u32Channel The channel(s) you want to delete.
+ ** \arg ADC1_CH0 ~ ADC1_CH16 Channels of ADC unit 1.
+ ** \arg ADC2_CH0 ~ ADC2_CH8 Channels of ADC unit 2.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ** \note You can use this function to delete ADC channel(s)
+ ** and then set the corresponding pin(s) of the channel(s)
+ ** to the other mode you need in your application.
+ **
+ ******************************************************************************/
+en_result_t ADC_DelAdcChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint16_t u16ChSelR0;
+ uint16_t u16ChSelR1;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ u16ChSelR0 = (uint16_t)u32Channel;
+ u16ChSelR1 = (uint16_t)(u32Channel >> 16u);
+
+ ADCx->CHSELRA0 &= (uint16_t)(~u16ChSelR0);
+ ADCx->CHSELRB0 &= (uint16_t)(~u16ChSelR0);
+
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->CHSELRA1 &= (uint16_t)(~u16ChSelR1);
+ ADCx->CHSELRB1 &= (uint16_t)(~u16ChSelR1);
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief ADC interrupt configuration.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u8Seq The sequence to be configured.
+ **
+ ** \param [in] enState Enable or Disable sequence conversion done interrupt.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_SeqITCmd(M4_ADC_TypeDef *ADCx,
+ uint8_t u8Seq,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint8_t u8Msk = 0u;
+
+ if ((NULL != ADCx) && (u8Seq <= ADC_SEQ_B))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ u8Msk = (uint8_t)(0x1ul << u8Seq);
+ ADCx->ISR &= (uint8_t)(~u8Msk);
+
+ if (Enable == enState)
+ {
+ ADCx->ICR |= u8Msk;
+ }
+ else
+ {
+ ADCx->ICR &= (uint8_t)(~u8Msk);
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief ADC average conversion configuration.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] enAvgCnt Average after enAvgCnt conversions.
+ ** See @ref en_adc_avcnt_t for details.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_ConfigAvg(M4_ADC_TypeDef *ADCx, en_adc_avcnt_t enAvgCnt)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_ADC_AVCNT(enAvgCnt));
+
+ ADCx->CR0_f.AVCNT = enAvgCnt;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Add average channel(s).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u32Channel The channel(s), which will be set as average channel(s).
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ** \note The channel must first be configured as an analog channel
+ ** by function ADC_AddAdcChannel.
+ **
+ ******************************************************************************/
+en_result_t ADC_AddAvgChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint16_t u16AvgChR0;
+ uint16_t u16AvgChR1;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (M4_ADC1 == ADCx)
+ {
+ u32Channel &= ADC1_CH_ALL;
+ }
+ else
+ {
+ u32Channel &= ADC2_CH_ALL;
+ }
+
+ u16AvgChR0 = (uint16_t)u32Channel;
+ u16AvgChR1 = (uint16_t)(u32Channel >> 16u);
+
+ ADCx->AVCHSELR0 |= u16AvgChR0;
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->AVCHSELR1 |= u16AvgChR1;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Delete average channel(s).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u32Channel The average channel(s) which you want to delete.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_DelAvgChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint16_t u16AvgChR0;
+ uint16_t u16AvgChR1;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ u16AvgChR0 = (uint16_t)u32Channel;
+ u16AvgChR1 = (uint16_t)(u32Channel >> 16u);
+
+ ADCx->AVCHSELR0 &= (uint16_t)(~u16AvgChR0);
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->AVCHSELR1 &= (uint16_t)(~u16AvgChR1);
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief ADC AWD(analog watch dog) configuration.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] pstcAwdCfg Pointer to the configuration structure.
+ ** See @ref stc_adc_awd_cfg_t for details.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_ConfigAwd(M4_ADC_TypeDef *ADCx, const stc_adc_awd_cfg_t *pstcAwdCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((NULL != ADCx) && (NULL != pstcAwdCfg))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_ADC_AWDMD(pstcAwdCfg->enAwdmd));
+ DDL_ASSERT(IS_ADC_AWDSS(pstcAwdCfg->enAwdss));
+
+ ADCx->AWDCR_f.AWDEN = AdcAwd_Disable;
+ ADCx->AWDCR_f.AWDIEN = AdcAwdInt_Disable;
+ ADCx->AWDCR_f.AWDMD = pstcAwdCfg->enAwdmd;
+ ADCx->AWDCR_f.AWDSS = pstcAwdCfg->enAwdss;
+
+ ADCx->AWDDR0 = pstcAwdCfg->u16AwdDr0;
+ ADCx->AWDDR1 = pstcAwdCfg->u16AwdDr1;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable ADC AWD(analog watch dog).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] enState Enable or disable AWD.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_AwdCmd(M4_ADC_TypeDef *ADCx, en_functional_state_t enState)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ ADCx->AWDCR_f.AWDEN = enState;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable ADC AWD(analog watch dog) interrupt.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] enState Enable or disable AWD interrupt.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_AwdITCmd(M4_ADC_TypeDef *ADCx, en_functional_state_t enState)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ ADCx->AWDCR_f.AWDIEN = enState;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Add AWD channel(s).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u32Channel The channel(s), which will be set as AWD channel(s).
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ** \note The channel must first be configured as an analog channel
+ ** by function ADC_AddAdcChannel.
+ **
+ ******************************************************************************/
+en_result_t ADC_AddAwdChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint16_t u16ChSelR0;
+ uint16_t u16ChSelR1;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (M4_ADC1 == ADCx)
+ {
+ u32Channel &= ADC1_CH_ALL;
+ }
+ else
+ {
+ u32Channel &= ADC2_CH_ALL;
+ }
+
+ u16ChSelR0 = (uint16_t)u32Channel;
+ u16ChSelR1 = (uint16_t)(u32Channel >> 16u);
+
+ ADCx->AWDCHSR0 |= u16ChSelR0;
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->AWDCHSR1 |= u16ChSelR1;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Delete AWD channel(s).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u32Channel The AWD channel(s) which you are going to delete.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_DelAwdChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint16_t u16ChSelR0;
+ uint16_t u16ChSelR1;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ u16ChSelR0 = (uint16_t)u32Channel;
+ u16ChSelR1 = (uint16_t)(u32Channel >> 16u);
+
+ ADCx->AWDCHSR0 &= (uint16_t)(~u16ChSelR0);
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->AWDCHSR1 &= (uint16_t)(~u16ChSelR1);
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief ADC programmable gain amplifier(PGA) configuration.
+ **
+ ** \param [in] enFactor PGA gain factor.
+ ** \param [in] enNegativeIn PGA negative input select.
+ **
+ ** \retval None.
+ **
+ ** \note Only ADC1 has PGA.
+ **
+ ******************************************************************************/
+void ADC_ConfigPga(en_adc_pga_factor_t enFactor, en_adc_pga_negative_t enNegativeIn)
+{
+ DDL_ASSERT(IS_ADC_PGA_FACTOR(enFactor));
+ DDL_ASSERT(IS_ADC_PGA_NEGATIVE(enNegativeIn));
+
+ M4_ADC1->PGAGSR_f.GAIN = enFactor;
+ M4_ADC1->PGAINSR1_f.PGAVSSEN = enNegativeIn;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable PGA.
+ **
+ ** \param [in] enState Enable or disable PGA.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void ADC_PgaCmd(en_functional_state_t enState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (Enable == enState)
+ {
+ M4_ADC1->PGACR_f.PGACTL = AdcPgaCtl_Amplify;
+ }
+ else
+ {
+ M4_ADC1->PGACR_f.PGACTL = AdcPgaCtl_Invalid;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Select PGA channel.
+ **
+ ** \param[in] u16Channel The channel, which you want to gain.
+ **
+ ** \retval None.
+ **
+ ** \note Only ADC1 has PGA. The channel must first
+ ** be configured as an analog channel
+ ** by function ADC_AddAdcChannel
+ **
+ ******************************************************************************/
+void ADC_PgaSelChannel(uint16_t u16Channel)
+{
+ DDL_ASSERT(IS_ADC_PGA_CH(u16Channel));
+ M4_ADC1->PGAINSR0 = u16Channel;
+}
+
+/**
+ *******************************************************************************
+ ** \brief ADC sync mode configuration.
+ **
+ ** \param [in] enMode Synchronous mode types.
+ ** \param [in] u8TrgDelay ADC2 trigger delay time.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void ADC_ConfigSync(en_adc_sync_mode_t enMode, uint8_t u8TrgDelay)
+{
+ DDL_ASSERT(IS_ADC_SYNC_MODE(enMode));
+
+ /* Disable synchronous mode first. */
+ M4_ADC1->SYNCCR_f.SYNCEN = AdcSync_Disable;
+
+ M4_ADC1->SYNCCR_f.SYNCMD = enMode;
+ M4_ADC1->SYNCCR_f.SYNCDLY = u8TrgDelay;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable sync mode.
+ **
+ ** \param [in] enState Enable or disable sync mode.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void ADC_SyncCmd(en_functional_state_t enState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ M4_ADC1->SYNCCR_f.SYNCEN = enState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Start an ADC conversion.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ** \note Software startup only support sequence A.
+ **
+ ******************************************************************************/
+en_result_t ADC_StartConvert(M4_ADC_TypeDef *ADCx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ ADCx->STR = 1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Stop an ADC conversion and clear flags.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval ErrorTimeout Timeout.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_StopConvert(M4_ADC_TypeDef *ADCx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO uint32_t u32TimeCount = 0u;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ enRet = Ok;
+ /* Make sure the ADC is really stopped. */
+ while (ADCx->STR == 1u)
+ {
+ /* Stop ADC conversion. */
+ ADCx->STR = 0u;
+ if (++u32TimeCount > 10000u)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the conversion status flag.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u8Seq The sequence which you want to get
+ ** it's conversion status flag.
+ **
+ ** \retval Set ADC converted done.
+ ** \retval Reset ADC is converting or parameter error.
+ **
+ ******************************************************************************/
+en_flag_status_t ADC_GetEocFlag(const M4_ADC_TypeDef *ADCx, uint8_t u8Seq)
+{
+ en_flag_status_t enFlag = Reset;
+
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (ADCx->ISR & ((uint8_t)(0x1ul << u8Seq)))
+ {
+ enFlag = Set;
+ }
+
+ return enFlag;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear conversion status flag of sequence A or sequence B.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u8Seq The sequence which you want to clear
+ ** it's conversion status flag.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void ADC_ClrEocFlag(M4_ADC_TypeDef *ADCx, uint8_t u8Seq)
+{
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ ADCx->ISR &= (uint8_t)(~(0x1ul << u8Seq));
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief ADC start sequence A, check it's EOC status and get the data.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [out] pu16AdcData The address to store ADC value.
+ ** The location of the data store depends on
+ ** the parameter u8Length.
+ ** u8Length >= ADCx_CH_COUNT(ADC1_CH_COUNT or ADC2_CH_COUNT),
+ ** all of the ADC data regs will be read:
+ ** pu16AdcData[0] = data of Channel 0,
+ ** pu16AdcData[1] = data of Channel 1,
+ ** pu16AdcData[2] = data of Channel 2,
+ ** ...
+ ** u8Length < ADCx_CH_COUNT(ADC1_CH_COUNT or ADC2_CH_COUNT),
+ ** only the data of the enabled channles will be read:
+ ** pu16AdcData[0] = data of the 1st enabled channel,
+ ** pu16AdcData[1] = data of the 2nd enabled channel,
+ ** pu16AdcData[2] = data of the 3rd enabled channel,
+ ** ...
+ **
+ ** \param [in] u8Length The length of the ADC data to be read.
+ **
+ ** \param [in] u32Timeout Timeout value.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval ErrorTimeout Timeout.
+ ** \retval OperationInProgress ADC is converting.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_PollingSa(M4_ADC_TypeDef *ADCx,
+ uint16_t *pu16AdcData,
+ uint8_t u8Length,
+ uint32_t u32Timeout)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint8_t u8AllDataLength = 0u;
+ uint32_t u32Channel = 0u;
+ uint32_t u32AdcTimeout = 0u;
+ __IO uint32_t u32TimeCount = 0u;
+
+ if ((NULL != ADCx) && (NULL != pu16AdcData) && (0u != u8Length))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (M4_ADC1 == ADCx)
+ {
+ if (u8Length >= ADC1_CH_COUNT)
+ {
+ u8AllDataLength = ADC1_CH_COUNT;
+ }
+ else
+ {
+ u32Channel = (uint32_t)ADCx->CHSELRA1;
+ u32Channel <<= 16u;
+ u32Channel |= (uint32_t)ADCx->CHSELRA0;
+ }
+ }
+ else
+ {
+ if (u8Length >= ADC2_CH_COUNT)
+ {
+ u8AllDataLength = ADC2_CH_COUNT;
+ }
+ else
+ {
+ u32Channel = (uint32_t)M4_ADC2->CHSELRA0;
+ }
+ }
+
+ /* Start ADC conversion. */
+ ADCx->STR = (uint8_t)0x01;
+
+ /* 10 is the number of required instructions cycles for the below loop statement. */
+ u32AdcTimeout = u32Timeout * (SystemCoreClock / 10u / 1000u);
+ u32TimeCount = 0u;
+ enRet = ErrorTimeout;
+ while (u32TimeCount < u32AdcTimeout)
+ {
+ if (ADCx->ISR_f.EOCAF)
+ {
+ /* Get ADC data. */
+ if (u8AllDataLength)
+ {
+ ADC_ReadAllData(ADCx, pu16AdcData, u8AllDataLength);
+ }
+ else
+ {
+ ADC_GetChData(ADCx, u32Channel, pu16AdcData, u8Length);
+ }
+
+ /* Clear sequence A flag. */
+ ADCx->ISR_f.EOCAF = 0u;
+ enRet = Ok;
+ break;
+ }
+ u32TimeCount++;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Reading all data regs of an ADC.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [out] pu16AdcData The address where the data will be stored.
+ ** pu16AdcData[0] = data of Channel 0,
+ ** pu16AdcData[1] = data of Channel 1,
+ ** pu16AdcData[2] = data of Channel 2,
+ ** ...
+ **
+ ** \param [in] u8Length The length of the ADC data to be read.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_GetAllData(const M4_ADC_TypeDef *ADCx, uint16_t *pu16AdcData, uint8_t u8Length)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ if (((M4_ADC1 == ADCx) && (u8Length >= ADC1_CH_COUNT)) ||
+ ((M4_ADC2 == ADCx) && (u8Length >= ADC2_CH_COUNT)))
+ {
+ ADC_ReadAllData(ADCx, pu16AdcData, u8Length);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Reading the data of the specified channel(s).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base
+ ** \arg M4_ADC1 ADC unit 1 instance register base
+ ** \arg M4_ADC2 ADC unit 2 instance register base
+ **
+ ** \param [in] u32TargetCh The specified channel(s)
+ **
+ ** \param [out] pu16AdcData The address where the data will be stored.
+ ** pu16AdcData[0] = data of the 1st enabled channel,
+ ** pu16AdcData[1] = data of the 2nd enabled channel,
+ ** pu16AdcData[2] = data of the 3rd enabled channel,
+ ** eg. u32TargetCh = 1001b
+ ** pu16AdcData[0] = Channel 0's data,
+ ** pu16AdcData[1] = Channel 3's data,
+ **
+ ** \param [in] u8Length The length of the ADC data to be read.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_GetChData(const M4_ADC_TypeDef *ADCx,
+ uint32_t u32TargetCh,
+ uint16_t *pu16AdcData,
+ uint8_t u8Length)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint8_t i;
+ uint8_t j;
+ uint32_t u32Channel;
+ __IO const uint16_t *pu16DataReg = &(ADCx->DR0);
+
+ if ((NULL != ADCx) && (NULL != pu16AdcData) && (0u != u8Length))
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (M4_ADC1 == ADCx)
+ {
+ u32Channel = u32TargetCh & ADC1_CH_ALL;
+ }
+ else
+ {
+ u32Channel = u32TargetCh & ADC2_CH_ALL;
+ }
+
+ i = 0u;
+ j = 0u;
+ while ((0u != u32Channel) && (0u != u8Length))
+ {
+ if (0u != (u32Channel & 0x1ul))
+ {
+ pu16AdcData[j] = pu16DataReg[i];
+ j++;
+ u8Length--;
+ }
+
+ u32Channel >>= 1u;
+ i++;
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the value of a specified channel via channel index.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base
+ ** \arg M4_ADC1 ADC unit 1 instance register base
+ ** \arg M4_ADC2 ADC unit 2 instance register base
+ **
+ ** \param [in] u8ChIndex The index of the specified channel.
+ ** u8ChIndex < ADC1_CH_COUNT while ADCx == M4_ADC1;
+ ** u8ChIndex < ADC2_CH_COUNT while ADCx == M4_ADC2.
+ **
+ ** \retval An uint16_t value -- the ADC value of the specified channel.
+ **
+ ******************************************************************************/
+uint16_t ADC_GetValue(const M4_ADC_TypeDef *ADCx, uint8_t u8ChIndex)
+{
+ __IO const uint16_t *pu16DataReg = &(ADCx->DR0);
+
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ return pu16DataReg[u8ChIndex];
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get all AWD channels status flags.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \retval u32AwdFlag 0 -- No ADC channel meets AWD comparison conditions.
+ ** !0 -- The bit value of the channel that satisfies the
+ ** AWD condition is 1.
+ **
+ ******************************************************************************/
+uint32_t ADC_GetAwdFlag(const M4_ADC_TypeDef *ADCx)
+{
+ uint32_t u32AwdFlag;
+
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (M4_ADC1 == ADCx)
+ {
+ u32AwdFlag = ADCx->AWDSR1;
+ u32AwdFlag <<= 16u;
+ u32AwdFlag |= ADCx->AWDSR0;
+ }
+ else
+ {
+ u32AwdFlag = ADCx->AWDSR0;
+ }
+
+ return u32AwdFlag;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear all AWD channels status flags
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void ADC_ClrAwdFlag(M4_ADC_TypeDef *ADCx)
+{
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ ADCx->AWDSR0 = 0u;
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->AWDSR0 = 0u;
+ ADCx->AWDSR1 = 0u;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear AWD specified channels status flags.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u32AwdCh The channel(s) which you want to clear it's flag(s).
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void ADC_ClrAwdChFlag(M4_ADC_TypeDef *ADCx, uint32_t u32AwdCh)
+{
+ uint16_t u16ChR0;
+ uint16_t u16ChR1;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ u16ChR0 = (uint16_t)u32AwdCh;
+ u16ChR1 = (uint16_t)(u32AwdCh >> 16u);
+
+ ADCx->AWDSR0 &= (uint16_t)(~u16ChR0);
+ if (M4_ADC1 == ADCx)
+ {
+ ADCx->AWDSR1 &= (uint16_t)(~u16ChR1);
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Remap an ADC pin to channel(s).
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u32DestChannel Destination channel(s).
+ **
+ ** \param [in] u8AdcPin ADC pin number.
+ **
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval Ok No error occurred.
+ **
+ ******************************************************************************/
+en_result_t ADC_ChannelRemap(M4_ADC_TypeDef *ADCx,
+ uint32_t u32DestChannel,
+ uint8_t u8AdcPin)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint8_t i;
+ uint8_t u8OffsetReg;
+ uint8_t u8ChPos;
+ uint16_t u16AdcPin = u8AdcPin;
+ __IO uint16_t *io16Chmuxr = NULL;
+
+ if (NULL != ADCx)
+ {
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+ enRet = Ok;
+ if (M4_ADC1 == ADCx)
+ {
+ if (u16AdcPin <= ADC1_IN15)
+ {
+ u32DestChannel &= ADC1_PIN_MASK_ALL;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+ else
+ {
+ if ((u16AdcPin >= ADC12_IN4) && (u16AdcPin <= ADC12_IN11))
+ {
+ u16AdcPin -= 4u;
+ u32DestChannel &= ADC2_PIN_MASK_ALL;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ if (Ok == enRet)
+ {
+ i = 0u;
+ while (0u != u32DestChannel)
+ {
+ if (u32DestChannel & 0x1ul)
+ {
+ u8OffsetReg = i / 4u;
+ u8ChPos = (i % 4u) * 4u;
+ io16Chmuxr = &(ADCx->CHMUXR0) + u8OffsetReg;
+ *io16Chmuxr &= (uint16_t)(~(0xFul << u8ChPos));
+ *io16Chmuxr |= (uint16_t)(u16AdcPin << u8ChPos);
+ }
+
+ u32DestChannel >>= 1u;
+ i++;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the number of the pin corresponding to the specified channel.
+ **
+ ** \param [in] ADCx Pointer to ADC instance register base.
+ ** \arg M4_ADC1 ADC unit 1 instance register base.
+ ** \arg M4_ADC2 ADC unit 2 instance register base.
+ **
+ ** \param [in] u8ChIndex This channel that you want to get its pin number.
+ **
+ ** \retval [0, 15] The correct ADC pin number.
+ ** \retval [0xFF] The invalid ADC pin number.
+ **
+ ******************************************************************************/
+uint8_t ADC_GetChannelPinNum(const M4_ADC_TypeDef *ADCx, uint8_t u8ChIndex)
+{
+ uint8_t u8OffsetPin;
+ uint8_t u8OffsetReg;
+ uint8_t u8ChPos;
+ uint8_t u8AdcPin = ADC_PIN_INVALID;
+ __IO const uint16_t *io16Chmuxr = NULL;
+
+ DDL_ASSERT(IS_ADC_PERIPH(ADCx));
+
+ if (M4_ADC1 == ADCx)
+ {
+ DDL_ASSERT(IS_ADC1_CH_INDEX(u8ChIndex));
+ u8OffsetPin = 0u;
+ }
+ else
+ {
+ DDL_ASSERT(IS_ADC2_CH_INDEX(u8ChIndex));
+ u8OffsetPin = 4u;
+ }
+
+ u8OffsetReg = u8ChIndex / 4u;
+ u8ChPos = (u8ChIndex % 4u) * 4u;
+ io16Chmuxr = &(ADCx->CHMUXR0) + u8OffsetReg;
+ u8AdcPin = (uint8_t)((*io16Chmuxr >> u8ChPos) & ((uint16_t)0xF));
+ u8AdcPin += u8OffsetPin;
+
+ return u8AdcPin;
+}
+
+/*******************************************************************************
+ * Function implementation - local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Read all data of an ADC. pu16AdcData[0] = DR0, pu16AdcData[1] = DR1, ...
+ **
+ ******************************************************************************/
+static void ADC_ReadAllData(const M4_ADC_TypeDef *ADCx, uint16_t *pu16AdcData, uint8_t u8Length)
+{
+ uint8_t i;
+ __IO const uint16_t *pu16DataReg = &(ADCx->DR0);
+
+ for (i = 0u; i < u8Length; i++)
+ {
+ pu16AdcData[i] = pu16DataReg[i];
+ }
+}
+
+//@} // AdcGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_aes.c b/lib/hc32f460/driver/src/hc32f460_aes.c new file mode 100644 index 00000000..84a0b9c5 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_aes.c @@ -0,0 +1,307 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_aes.c
+ **
+ ** A detailed description is available at
+ ** @link AesGroup Aes description @endlink
+ **
+ ** - 2018-10-20 CDT First version for Device Driver Library of Aes.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_aes.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup AesGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/* AES block length in bytes is 16. */
+#define AES_BLOCK_LEN ((uint8_t)16)
+
+/* Each encryption operation takes 440 system clock cycles. */
+#define AES_ENCRYPT_TIMEOUT (440u)
+
+/* Each decryption operation takes 580 system clock cycles. */
+#define AES_DECRYPT_TIMEOUT (580u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+static void AES_WriteData(const uint8_t *pu8SrcData);
+static void AES_ReadData(uint8_t *pu8Dest);
+static void AES_WriteKey(const uint8_t *pu8Key);
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief AES128 encryption(ECB mode).
+ **
+ ** \param [in] pu8Plaintext Pointer to plaintext(the source data which will be encrypted)
+ **
+ ** \param [in] u32PlaintextSize Length of plaintext in bytes.
+ **
+ ** \param [in] pu8Key Pointer to the AES key.
+ **
+ ** \param [out] pu8Ciphertext The destination address to store the result of the encryption.
+ **
+ ** \retval Ok No error occurred.
+ ** \retval ErrorTimeout AES works timeout.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t AES_Encrypt(const uint8_t *pu8Plaintext,
+ uint32_t u32PlaintextSize,
+ const uint8_t *pu8Key,
+ uint8_t *pu8Ciphertext)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint32_t u32BlockOffset;
+ uint32_t u32Index;
+ __IO uint32_t u32TimeCount;
+
+ if ((NULL != pu8Plaintext) &&
+ (0u != u32PlaintextSize) &&
+ (NULL != pu8Key) &&
+ (NULL != pu8Ciphertext) &&
+ (0u == (u32PlaintextSize & 0xFu)) && /* u32PlaintextSize % AES_BLOCK_LEN */
+ (0u == ((uint32_t)pu8Plaintext & 0x3u)) && /* (uint32_t)pu8Ciphertext % 4u */
+ (0u == ((uint32_t)pu8Key & 0x3u)) && /* (uint32_t)pu8Key % 4u */
+ (0u == ((uint32_t)pu8Ciphertext & 0x3u))) /* (uint32_t)pu8Plaintext % 4u */
+ {
+ /* Write the key to the register. */
+ AES_WriteKey(pu8Key);
+ u32BlockOffset = 0u;
+ while (0u != u32PlaintextSize)
+ {
+ /* Stop AES calculating. */
+ bM4_AES_CR_START = 0u;
+
+ /* Write data. */
+ u32Index = u32BlockOffset * AES_BLOCK_LEN;
+ AES_WriteData(&pu8Plaintext[u32Index]);
+
+ /* Set AES encrypt. */
+ bM4_AES_CR_MODE = 0u;
+
+ /* Start AES calculating. */
+ bM4_AES_CR_START = 1u;
+
+ enRet = ErrorTimeout;
+ u32TimeCount = 0u;
+ while (u32TimeCount < AES_ENCRYPT_TIMEOUT)
+ {
+ if (bM4_AES_CR_START == 0u)
+ {
+ enRet = Ok;
+ break;
+ }
+ u32TimeCount++;
+ }
+
+ if (enRet == ErrorTimeout)
+ {
+ break;
+ }
+
+ AES_ReadData(&pu8Ciphertext[u32Index]);
+ u32PlaintextSize -= AES_BLOCK_LEN;
+ u32BlockOffset++;
+ }
+
+ /* Stop AES calculating. */
+ bM4_AES_CR_START = 0u;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief AES128 decryption(ECB mode).
+ **
+ ** \param [in] pu8Ciphertext Pointer to ciphertext(the source data which will be decrypted)
+ **
+ ** \param [in] u32CiphertextSize Length of ciphertext in bytes.
+ **
+ ** \param [in] pu8Key Pointer to the AES key.
+ **
+ ** \param [out] pu8Plaintext The destination address to store the result of the decryption.
+ **
+ ** \retval Ok No error occurred.
+ ** \retval ErrorTimeout AES works timeout.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t AES_Decrypt(const uint8_t *pu8Ciphertext,
+ uint32_t u32CiphertextSize,
+ const uint8_t *pu8Key,
+ uint8_t *pu8Plaintext)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint32_t u32BlockOffset;
+ uint32_t u32Index;
+ __IO uint32_t u32TimeCount;
+
+ if ((NULL != pu8Ciphertext) &&
+ (0u != u32CiphertextSize) &&
+ (NULL != pu8Key) &&
+ (NULL != pu8Plaintext) &&
+ (0u == (u32CiphertextSize & 0xFu)) && /* u32CiphertextSize % AES_BLOCK_LEN */
+ (0u == ((uint32_t)pu8Ciphertext & 0x3u)) && /* (uint32_t)pu8Ciphertext % 4u */
+ (0u == ((uint32_t)pu8Key & 0x3u)) && /* (uint32_t)pu8Key % 4u */
+ (0u == ((uint32_t)pu8Plaintext & 0x3u))) /* (uint32_t)pu8Plaintext % 4u */
+ {
+ /* Write the key to the register. */
+ AES_WriteKey(pu8Key);
+ u32BlockOffset = 0u;
+ while (0u != u32CiphertextSize)
+ {
+ /* Stop AES calculating. */
+ bM4_AES_CR_START = 0u;
+
+ /* Write data. */
+ u32Index = u32BlockOffset * AES_BLOCK_LEN;
+ AES_WriteData(&pu8Ciphertext[u32Index]);
+
+ /* Set AES decrypt. */
+ bM4_AES_CR_MODE = 1u;
+
+ /* Start AES calculating. */
+ bM4_AES_CR_START = 1u;
+
+ enRet = ErrorTimeout;
+ u32TimeCount = 0u;
+ while (u32TimeCount < AES_DECRYPT_TIMEOUT)
+ {
+ if (bM4_AES_CR_START == 0u)
+ {
+ enRet = Ok;
+ break;
+ }
+ u32TimeCount++;
+ }
+
+ if (enRet == ErrorTimeout)
+ {
+ break;
+ }
+
+ AES_ReadData(&pu8Plaintext[u32Index]);
+ u32CiphertextSize -= AES_BLOCK_LEN;
+ u32BlockOffset++;
+ }
+
+ /* Stop AES calculating. */
+ bM4_AES_CR_START = 0u;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * Function implementation - local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Writes the input buffer in data register.
+ **
+ ** \param [in] pu8SrcData Pointer to source data buffer.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+static void AES_WriteData(const uint8_t *pu8SrcData)
+{
+ uint8_t i;
+ uint32_t u32SrcAddr = (uint32_t)pu8SrcData;
+ uint32_t u32DrAddr = (uint32_t)&(M4_AES->DR0);
+
+ for (i = 0u; i < 4u; i++)
+ {
+ *(__IO uint32_t *)u32DrAddr = *(uint32_t*)u32SrcAddr;
+ u32SrcAddr += 4u;
+ u32DrAddr += 4u;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Reads the from data register.
+ **
+ ** \param [out] pu8Dest Pointer to the destination buffer.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+static void AES_ReadData(uint8_t *pu8Dest)
+{
+ uint8_t i;
+ uint32_t u32DestAddr = (uint32_t)pu8Dest;
+ uint32_t u32DrAddr = (uint32_t)&(M4_AES->DR0);
+
+ for (i = 0u; i < 4u; i++)
+ {
+ *(uint32_t*)u32DestAddr = *(__IO uint32_t *)u32DrAddr;
+ u32DestAddr += 4u;
+ u32DrAddr += 4u;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Writes the input buffer in key register.
+ **
+ ** \param [in] pu8Key Pointer to AES key.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+static void AES_WriteKey(const uint8_t *pu8Key)
+{
+ uint8_t i;
+ uint32_t u32SrcKeyAddr = (uint32_t)pu8Key;
+ uint32_t u32KeyAddr = (uint32_t)&(M4_AES->KR0);
+
+ for (i = 0u; i < 4u; i++)
+ {
+ *(__IO uint32_t *)u32KeyAddr = *(uint32_t*)u32SrcKeyAddr;
+ u32SrcKeyAddr += 4u;
+ u32KeyAddr += 4u;
+ }
+}
+
+//@} // AesGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_can.c b/lib/hc32f460/driver/src/hc32f460_can.c new file mode 100644 index 00000000..54ffe366 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_can.c @@ -0,0 +1,558 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_can.c
+ **
+ ** A detailed description is available at
+ ** @link CanGroup CAN description @endlink
+ **
+ ** - 2018-12-13 CDT First version for Device Driver Library of CAN.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_can.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup CanGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define CAN_RESET_ENABLE() (M4_CAN->CFG_STAT_f.RESET = 1u)
+#define CAN_RESET_DISABLE() \
+do{ \
+ do{ \
+ M4_CAN->CFG_STAT_f.RESET = 0u; \
+}while(M4_CAN->CFG_STAT_f.RESET); \
+}while(0)
+
+#define CAN_RW_MEM32(addr) (*(__IO uint32_t *)(addr))
+
+#define CAN_ACF_ID_REG_SEL ((uint8_t)0x00u)
+#define CAN_ACF_MASK_REG_SEL ((uint8_t)0x01u)
+
+
+/*! Parameter validity check for CAN Mode \a CanMode. */
+#define IS_CAN_MODE_VALID(CanMode) \
+( (CanExternalLoopBackMode == (CanMode)) || \
+ (CanInternalLoopBackMode == (CanMode)) || \
+ (CanTxSignalPrimaryMode == (CanMode)) || \
+ (CanTxSignalSecondaryMode == (CanMode)) || \
+ (CanListenOnlyMode == (CanMode)) \
+)
+
+/*! Parameter validity check for CAN Tx Cmd \a TxCmd. */
+#define IS_TX_CMD_VALID(TxCmd) \
+( (CanPTBTxCmd == (TxCmd)) || \
+ (CanPTBTxAbortCmd == (TxCmd)) || \
+ (CanSTBTxOneCmd == (TxCmd)) || \
+ (CanSTBTxAllCmd == (TxCmd)) || \
+ (CanSTBTxAbortCmd == (TxCmd)) \
+)
+
+/*! Parameter validity check for CAN status \a enCanStatus. */
+#define IS_CAN_STATUS_VALID(enCanStatus) \
+( (CanRxActive == (enCanStatus)) || \
+ (CanTxActive == (enCanStatus)) || \
+ (CanBusoff == (enCanStatus)) \
+)
+
+/*! Parameter validity check for CAN Irq type \a enCanIrqType. */
+#define IS_CAN_IRQ_TYPE_VALID(enCanIrqType) \
+( (CanRxIrqEn == (enCanIrqType)) || \
+ (CanRxOverIrqEn == (enCanIrqType)) || \
+ (CanRxBufFullIrqEn == (enCanIrqType)) || \
+ (CanRxBufAlmostFullIrqEn == (enCanIrqType)) || \
+ (CanTxPrimaryIrqEn == (enCanIrqType)) || \
+ (CanTxSecondaryIrqEn == (enCanIrqType)) || \
+ (CanErrorIrqEn == (enCanIrqType)) || \
+ (CanErrorPassiveIrqEn == (enCanIrqType)) || \
+ (CanArbiLostIrqEn == (enCanIrqType)) || \
+ (CanBusErrorIrqEn == (enCanIrqType)) \
+)
+
+/*! Parameter validity check for CAN Irq flag type \a enCanIrqFLg. */
+#define IS_CAN_IRQ_FLAG_VALID(enCanIrqFLg) \
+( (CanTxBufFullIrqFlg == (enCanIrqFLg)) || \
+ (CanRxIrqFlg == (enCanIrqFLg)) || \
+ (CanRxOverIrqFlg == (enCanIrqFLg)) || \
+ (CanRxBufFullIrqFlg == (enCanIrqFLg)) || \
+ (CanRxBufAlmostFullIrqFlg == (enCanIrqFLg)) || \
+ (CanTxPrimaryIrqFlg == (enCanIrqFLg)) || \
+ (CanTxSecondaryIrqFlg == (enCanIrqFLg)) || \
+ (CanErrorIrqFlg == (enCanIrqFLg)) || \
+ (CanAbortIrqFlg == (enCanIrqFLg)) || \
+ (CanErrorWarningIrqFlg == (enCanIrqFLg)) || \
+ (CanErrorPassivenodeIrqFlg == (enCanIrqFLg)) || \
+ (CanErrorPassiveIrqFlg == (enCanIrqFLg)) || \
+ (CanArbiLostIrqFlg == (enCanIrqFLg)) || \
+ (CanBusErrorIrqFlg == (enCanIrqFLg)) \
+)
+
+/*! Parameter validity check for CAN filter \a enCanFilter. */
+#define IS_CAN_FILTER_VALID(enCanFilter) \
+( (enCanFilter) <= CanFilterSel8)
+
+/*! Parameter validity check for CAN filter count \a u8Count. */
+#define IS_CAN_FILTER_COUNT_VALID(u8Count) \
+( (u8Count) <= 8u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Configures the can base functions
+ **
+ ** \param [in] pstcCanInitCfg The can initial config struct.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_Init(const stc_can_init_config_t *pstcCanInitCfg)
+{
+ uint8_t i;
+ if (NULL != pstcCanInitCfg)
+ {
+ DDL_ASSERT(IS_CAN_FILTER_COUNT_VALID(pstcCanInitCfg->u8FilterCount));
+
+ CAN_RESET_ENABLE();
+ M4_CAN->BT_f.PRESC = pstcCanInitCfg->stcCanBt.PRESC;
+ M4_CAN->BT_f.SEG_1 = pstcCanInitCfg->stcCanBt.SEG_1;
+ M4_CAN->BT_f.SEG_2 = pstcCanInitCfg->stcCanBt.SEG_2;
+ M4_CAN->BT_f.SJW = pstcCanInitCfg->stcCanBt.SJW;
+ M4_CAN->TCTRL_f.TSMODE = pstcCanInitCfg->enCanSTBMode;
+ CAN_FilterConfig(pstcCanInitCfg->pstcFilter, pstcCanInitCfg->u8FilterCount);
+
+ CAN_RESET_DISABLE();
+ M4_CAN->RCTRL_f.RBALL = pstcCanInitCfg->enCanRxBufAll;
+ M4_CAN->RCTRL_f.ROM = pstcCanInitCfg->enCanRxBufMode;
+ M4_CAN->RCTRL_f.SACK = pstcCanInitCfg->enCanSAck;
+ M4_CAN->LIMIT_f.AFWL = pstcCanInitCfg->stcWarningLimit.CanWarningLimitVal;
+ M4_CAN->LIMIT_f.EWL = pstcCanInitCfg->stcWarningLimit.CanErrorWarningLimitVal;
+
+ // Enable filters.
+ for (i=0u; i<pstcCanInitCfg->u8FilterCount; i++)
+ {
+ CAN_FilterCmd(pstcCanInitCfg->pstcFilter[i].enFilterSel, Enable);
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Init (RESET CAN register)
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_DeInit(void)
+{
+ CAN_RESET_ENABLE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the can Mode
+ **
+ ** \param [in] enMode The can mode enum. @ref en_can_mode_t
+ ** \param [in] enNewState The new state of the can filter chanel.
+ ** \arg Enable Enable filter.
+ ** \arg Disable Disable filter.
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_ModeConfig(en_can_mode_t enMode, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_CAN_MODE_VALID(enMode));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(CanListenOnlyMode == enMode)
+ {
+ M4_CAN->TCMD_f.LOM = enNewState;
+ }else
+ {
+ if(Enable == enNewState)
+ {
+ M4_CAN->CFG_STAT |= enMode;
+ }else
+ {
+ M4_CAN->CFG_STAT &= ~enMode;
+ }
+ }
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Configures the can acceptance filter
+ **
+ ** \param [in] pstcFilter Pointer to a stc_can_filter_t type array.
+ ** @ref stc_can_filter_t
+ ** \param [in] u8FilterCount Number of filters that to be configured.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_FilterConfig(const stc_can_filter_t pstcFilter[], uint8_t u8FilterCount)
+{
+ uint8_t i;
+
+ if(NULL != pstcFilter)
+ {
+ DDL_ASSERT(IS_CAN_FILTER_COUNT_VALID(u8FilterCount));
+
+ for (i=0u; i<u8FilterCount; i++)
+ {
+ DDL_ASSERT(IS_CAN_FILTER_VALID(pstcFilter[i].enFilterSel));
+ //<<Acceptance filter address
+ M4_CAN->ACFCTRL_f.ACFADR = pstcFilter[i].enFilterSel;
+ //<<ID config
+ M4_CAN->ACFCTRL_f.SELMASK = CAN_ACF_ID_REG_SEL;
+ M4_CAN->ACF = pstcFilter[i].u32CODE;
+ //<<MASK config
+ M4_CAN->ACFCTRL_f.SELMASK = CAN_ACF_MASK_REG_SEL;
+ M4_CAN->ACF = pstcFilter[i].u32MASK;
+ //<<Frame format config
+ M4_CAN->ACF_f.AIDEE = ((pstcFilter[i].enAcfFormat >> 1ul) & 0x01u);
+ M4_CAN->ACF_f.AIDE = (pstcFilter[i].enAcfFormat & 0x01ul);
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the specified can acceptance filter.
+ **
+ ** \param [in] enFilter Specifies a filter.
+ ** @ref en_can_filter_sel_t
+ ** \param [in] enNewState The new state of the specified filter.
+ ** \arg Enable Enable.
+ ** \arg Disable Disable.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_FilterCmd(en_can_filter_sel_t enFilter, en_functional_state_t enNewState)
+{
+ uint8_t u8FilterSel;
+
+ DDL_ASSERT(IS_CAN_FILTER_VALID(enFilter));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ u8FilterSel = (uint8_t)(1ul << enFilter);
+
+ if(Enable == enNewState)
+ {
+ M4_CAN->ACFEN |= u8FilterSel;
+ }else
+ {
+ M4_CAN->ACFEN &= (uint8_t)(~u8FilterSel);
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the can Tx frame set
+ **
+ ** \param [in] pstcTxFrame The can Tx frame struct.
+ ** @ref stc_can_txframe_t
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_SetFrame(stc_can_txframe_t *pstcTxFrame)
+{
+ uint32_t u32TBUFAddr;
+
+ if(NULL != pstcTxFrame)
+ {
+ u32TBUFAddr = (uint32_t)&M4_CAN->TBUF;
+ M4_CAN->TCMD_f.TBSEL = pstcTxFrame->enBufferSel;
+ CAN_RW_MEM32(u32TBUFAddr) = pstcTxFrame->TBUF32_0;
+ CAN_RW_MEM32(u32TBUFAddr+4) = pstcTxFrame->TBUF32_1;
+ CAN_RW_MEM32(u32TBUFAddr+8) = pstcTxFrame->TBUF32_2[0];
+ CAN_RW_MEM32(u32TBUFAddr+12) = pstcTxFrame->TBUF32_2[1];
+
+ if(CanSTBSel == pstcTxFrame->enBufferSel)
+ {
+ M4_CAN->TCTRL_f.TSNEXT = Enable;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the can Tx Command
+ **
+ ** \param [in] enTxCmd The can Tx Command.
+ **
+ ** \retval Can Tx buffer status @ref en_can_tx_buf_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_can_tx_buf_status_t CAN_TransmitCmd(en_can_tx_cmd_t enTxCmd)
+{
+ DDL_ASSERT(IS_TX_CMD_VALID(enTxCmd));
+
+ M4_CAN->TCMD |= enTxCmd;
+
+ return (en_can_tx_buf_status_t)M4_CAN->TCTRL_f.TSSTAT;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the can Rx frame
+ **
+ ** \param [in] pstcRxFrame The can Rx frame.
+ ** @ref stc_can_rxframe_t
+ ** \retval Can rx buffer status @ref en_can_rx_buf_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_can_rx_buf_status_t CAN_Receive(stc_can_rxframe_t *pstcRxFrame)
+{
+ uint32_t u32RBUFAddr;
+
+ if(NULL != pstcRxFrame)
+ {
+ u32RBUFAddr = (uint32_t)&M4_CAN->RBUF;
+ pstcRxFrame->RBUF32_0 = CAN_RW_MEM32(u32RBUFAddr);
+ pstcRxFrame->RBUF32_1 = CAN_RW_MEM32(u32RBUFAddr+4);
+ pstcRxFrame->RBUF32_2[0] = CAN_RW_MEM32(u32RBUFAddr+8);
+ pstcRxFrame->RBUF32_2[1] = CAN_RW_MEM32(u32RBUFAddr+12);
+
+ M4_CAN->RCTRL_f.RREL = 1u;
+ }
+ return (en_can_rx_buf_status_t)M4_CAN->RCTRL_f.RSTAT;
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Get the can Error Status
+ **
+ ** \param None
+ **
+ ** \retval en_can_error_t The can error status
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_can_error_t CAN_ErrorStatusGet(void)
+{
+ en_can_error_t enRet = UNKOWN_ERROR;
+
+ if(6u > M4_CAN->EALCAP_f.KOER)
+ {
+ enRet = (en_can_error_t)M4_CAN->EALCAP_f.KOER;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the can Status
+ **
+ ** \param enCanStatus The can status
+ ** \arg true
+ ** \arg false
+ ** \retval bool
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+bool CAN_StatusGet(en_can_status_t enCanStatus)
+{
+ bool bRet = false;
+ DDL_ASSERT(IS_CAN_STATUS_VALID(enCanStatus));
+
+ if(M4_CAN->CFG_STAT & enCanStatus)
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the can Interrupt enable
+ **
+ ** \param [in] enCanIrqType The can interrupt type.
+ ** \param [in] enNewState The new state of the can interrupt.
+ ** \arg Enable Enable.
+ ** \arg Disable Disable.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_IrqCmd(en_can_irq_type_t enCanIrqType, en_functional_state_t enNewState)
+{
+ volatile uint32_t *u32pIE;
+
+ DDL_ASSERT(IS_CAN_IRQ_TYPE_VALID(enCanIrqType));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ u32pIE = (volatile uint32_t*)(&M4_CAN->RTIE);
+
+ if(Enable == enNewState)
+ {
+ *u32pIE |= enCanIrqType;
+ }else
+ {
+ *u32pIE &= ~((uint32_t)enCanIrqType);
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the can Interrupt Flag
+ **
+ ** \param [in] enCanIrqFlgType The can interrupt Flag.
+ **
+ ** \retval bool
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+bool CAN_IrqFlgGet(en_can_irq_flag_type_t enCanIrqFlgType)
+{
+ volatile uint32_t *u32pIE = NULL;
+ bool bRet = false;
+
+ DDL_ASSERT(IS_CAN_IRQ_FLAG_VALID(enCanIrqFlgType));
+
+ u32pIE = (volatile uint32_t*)(&M4_CAN->RTIE);
+
+ if( *u32pIE & enCanIrqFlgType)
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the can Interrupt Flag
+ **
+ ** \param [in] enCanIrqFlgType The can interrupt type.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CAN_IrqFlgClr(en_can_irq_flag_type_t enCanIrqFlgType)
+{
+ volatile uint32_t *u32pIE = NULL;
+ uint32_t u32IETempMsk = 0xFF2A00FF;
+
+ DDL_ASSERT(IS_CAN_IRQ_FLAG_VALID(enCanIrqFlgType));
+
+ u32pIE = (volatile uint32_t*)(&M4_CAN->RTIE);
+
+ *u32pIE = (((*u32pIE)&u32IETempMsk) | (uint32_t)enCanIrqFlgType);
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Get the can Rx Error Counter
+ **
+ ** \param None
+ **
+ ** \retval Error Counter(0~255)
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint8_t CAN_RxErrorCntGet(void)
+{
+ return M4_CAN->RECNT;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the can Tx Error Counter
+ **
+ ** \param None
+ **
+ ** \retval Error Counter(0~255)
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint8_t CAN_TxErrorCntGet(void)
+{
+ return M4_CAN->TECNT;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the can Arbitration lost captrue
+ **
+ ** \param None
+ **
+ ** \retval address(0~31)
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint8_t CAN_ArbitrationLostCap(void)
+{
+ return M4_CAN->EALCAP_f.ALC;
+}
+
+
+//@} // CanGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
+
diff --git a/lib/hc32f460/driver/src/hc32f460_clk.c b/lib/hc32f460/driver/src/hc32f460_clk.c new file mode 100644 index 00000000..53055e83 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_clk.c @@ -0,0 +1,1839 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_clk.c
+ **
+ ** A detailed description is available at
+ ** @link CmuGroup Clock description @endlink
+ **
+ ** - 2018-10-13 CDT First version for Device Driver Library of CMU.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_clk.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup CmuGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define CLK_XTAL_TIMEOUT ((uint16_t)0x1000u)
+#define CLK_XTAL32_TIMEOUT ((uint8_t)0x05u)
+#define CLK_HRC_TIMEOUT ((uint16_t)0x1000u)
+#define CLK_MRC_TIMEOUT ((uint8_t)0x05u)
+#define CLK_LRC_TIMEOUT ((uint8_t)0x05u)
+#define CLK_MPLL_TIMEOUT ((uint16_t)0x1000u)
+#define CLK_UPLL_TIMEOUT ((uint16_t)0x1000u)
+
+/* TBDs 30us based 200M frequency. */
+#define CLK_FCG_STABLE ((uint16_t)0x200u)
+#define CLK_SYSCLK_STABLE ((uint16_t)0x200u)
+#define CLK_USBCLK_STABLE ((uint16_t)0x200u)
+
+#define CLK_PLL_DIV_MIN (2u)
+#define CLK_PLL_DIV_MAX (16u)
+
+#define CLK_PLLQ_DIV_MIN (1u)
+#define CLK_PLLQ_DIV_MAX (16u)
+
+#define CLK_PLLN_MIN (20u)
+#define CLK_PLLN_MAX (480u)
+
+#define CLK_PLLM_MIN (1u)
+#define CLK_PLLM_MAX (24u)
+
+#define CLK_UPLLM_MIN (2u)
+#define CLK_UPLLM_MAX (24u)
+
+#define CLK_PLL_VCO_IN_MIN (1u*1000u*1000u)
+#define CLK_PLL_VCO_IN_MAX (24u*1000u*1000u)
+
+#define CLK_PLL_VCO_OUT_MIN (240u*1000u*1000u)
+#define CLK_PLL_VCO_OUT_MAX (480u*1000u*1000u)
+
+#define ENABLE_FCG0_REG_WRITE() (M4_MSTP->FCG0PC = 0xa5a50001u)
+#define DISABLE_FCG0_REG_WRITE() (M4_MSTP->FCG0PC = 0xa5a50000u)
+
+#define ENABLE_CLOCK_REG_WRITE() (M4_SYSREG->PWR_FPRC |= 0xa501u)
+#define DISABLE_CLOCK_REG_WRITE() (M4_SYSREG->PWR_FPRC = (0xa500u | (M4_SYSREG->PWR_FPRC & (uint16_t)(~1u))))
+
+#define ENABLE_CLOCK1_REG_WRITE() (M4_SYSREG->PWR_FPRC |= 0xa502u)
+#define DISABLE_CLOCK1_REG_WRITE() (M4_SYSREG->PWR_FPRC = (0xa500u | (M4_SYSREG->PWR_FPRC & (uint16_t)(~2u))))
+
+
+#define DEFAULT_FCG0 (0xFFFFFAEEul)
+#define DEFAULT_FCG1 (0xFFFFFFFFul)
+#define DEFAULT_FCG2 (0xFFFFFFFFul)
+#define DEFAULT_FCG3 (0xFFFFFFFFul)
+#define FCG2_WITHOUT_EMB (0xFFFF7FFFul)
+
+#define FCG0_OFFSET_FCM (16ul)
+#define FCG1_OFFSET_CAN (0ul)
+#define FCG1_OFFSET_QSPI (3ul)
+#define FCG1_OFFSET_USBFS (8ul)
+#define FCG1_OFFSET_SPI1 (16ul)
+#define FCG1_OFFSET_SPI2 (17ul)
+#define FCG1_OFFSET_SPI3 (18ul)
+#define FCG1_OFFSET_SPI4 (19ul)
+#define FCG3_OFFSET_ADC1 (0ul)
+#define FCG3_OFFSET_ADC2 (1ul)
+#define FCG3_OFFSET_DAC (4ul)
+
+/*! Parameter validity check for XTAL stablization time \a stb. */
+#define IS_XTAL_STB_VALID(stb) \
+( (ClkXtalStbCycle35 <= (stb)) && \
+ (ClkXtalStbCycle8163 >= (stb)))
+
+/*! Parameter validity check for pll source \a src. */
+#define IS_PLL_SOURCE(src) \
+( (ClkPllSrcXTAL == (src)) || \
+ (ClkPllSrcHRC == (src)))
+
+/*! Parameter validity check for mpll div \a pllp, pllr, upll div \a pllp, pllq, pllr*/
+#define IS_PLL_DIV_VALID(pllx) \
+( (CLK_PLL_DIV_MIN <= (pllx)) && \
+ (CLK_PLL_DIV_MAX >= (pllx)))
+
+/*! Parameter validity check for pll div \a pllq. */
+#define IS_PLLQ_DIV_VALID(pllx) \
+( (CLK_PLLQ_DIV_MIN <= (pllx)) && \
+ (CLK_PLLQ_DIV_MAX >= (pllx)))
+
+/*! Parameter validity check for plln \a plln. */
+#define IS_PLLN_VALID(plln) \
+( (CLK_PLLN_MIN <= (plln)) && \
+ (CLK_PLLN_MAX >= (plln)))
+
+/*! Parameter validity check for pllm \a pllm. */
+#define IS_PLLM_VALID(pllm) \
+( (CLK_PLLM_MIN <= (pllm)) && \
+ (CLK_PLLM_MAX >= (pllm)))
+
+/*! Parameter validity check for pllm \a pllm. */
+#define IS_UPLLM_VALID(pllm) \
+( (CLK_UPLLM_MIN <= (pllm)) && \
+ (CLK_UPLLM_MAX >= (pllm)))
+
+/*! Parameter validity check for pllsource/pllm \a vco_in. */
+#define IS_PLL_VCO_IN_VALID(vco_in) \
+( (CLK_PLL_VCO_IN_MIN <= (vco_in)) && \
+ (CLK_PLL_VCO_IN_MAX >= (vco_in)))
+
+/*! Parameter validity check for pllsource/pllm*plln \a vco_out. */
+#define IS_PLL_VCO_OUT_VALID(vco_out) \
+( (CLK_PLL_VCO_OUT_MIN <= (vco_out)) && \
+ (CLK_PLL_VCO_OUT_MAX >= (vco_out)))
+
+/*! Parameter validity check for system clock source \a syssrc. */
+#define IS_SYSCLK_SOURCE(syssrc) \
+( (ClkSysSrcHRC == (syssrc)) || \
+ ((ClkSysSrcMRC <= (syssrc)) && \
+ (CLKSysSrcMPLL >= (syssrc))))
+
+/*! Parameter validity check for usb clock source \a usbsrc. */
+#define IS_USBCLK_SOURCE(usbsrc) \
+( ((ClkUsbSrcSysDiv2 <= (usbsrc)) && \
+ (ClkUsbSrcSysDiv4 >= (usbsrc))) || \
+ ((ClkUsbSrcMpllp <= (usbsrc)) && \
+ (ClkUsbSrcUpllr >= (usbsrc))))
+
+/*! Parameter validity check for peripheral(adc/trng/I2S) clock source \a adcsrc. */
+#define IS_PERICLK_SOURCE(adcsrc) \
+( (ClkPeriSrcPclk == (adcsrc)) || \
+ ((ClkPeriSrcMpllp <= (adcsrc)) && \
+ (ClkPeriSrcUpllr >= (adcsrc))))
+
+/*! Parameter validity check for output clock source \a outsrc. */
+#define IS_OUTPUTCLK_SOURCE(outsrc) \
+( (ClkOutputSrcHrc == (outsrc)) || \
+ (ClkOutputSrcMrc == (outsrc)) || \
+ (ClkOutputSrcLrc == (outsrc)) || \
+ (ClkOutputSrcXtal == (outsrc)) || \
+ (ClkOutputSrcXtal32 == (outsrc)) || \
+ (ClkOutputSrcMpllp == (outsrc)) || \
+ (ClkOutputSrcUpllp == (outsrc)) || \
+ (ClkOutputSrcMpllq == (outsrc)) || \
+ (ClkOutputSrcUpllq == (outsrc)) || \
+ (ClkOutputSrcSysclk == (outsrc)))
+
+/*! Parameter validity check for fcm source \a fcmsrc. */
+#define IS_FCM_SOURCE(fcmsrc) \
+( (ClkFcmSrcXtal == (fcmsrc)) || \
+ ((ClkFcmSrcXtal32 <= (fcmsrc)) && \
+ (ClkFcmSrcRtcLrc >= (fcmsrc))))
+
+/*! Parameter validity check for output clock channel \a outch. */
+#define IS_OUTPUTCLK_CHANNEL(outch) \
+( (ClkOutputCh1 == (outch)) || \
+ (ClkOutputCh2 == (outch)))
+
+/*! Parameter validity check for fcm reference \a ref. */
+#define IS_FCM_REF(ref) \
+( (ClkFcmExtRef == (ref)) || \
+ (ClkFcmInterRef == (ref)))
+
+/*! Parameter validity check for fcm edge \a edge. */
+#define IS_FCM_EDGE(edge) \
+( (ClkFcmEdgeRising == (edge)) || \
+ (ClkFcmEdgeFalling == (edge)) || \
+ (ClkFcmEdgeBoth == (edge)))
+
+/*! Parameter validity check for fcm filter clock \a clk. */
+#define IS_FCM_FILTER_CLK(clk) \
+( (ClkFcmFilterClkNone == (clk)) || \
+ (ClkFcmFilterClkFcmSrc == (clk)) || \
+ (ClkFcmFilterClkFcmSrcDiv4 == (clk)) || \
+ (ClkFcmFilterClkFcmSrcDiv16 == (clk)))
+
+/*! Parameter validity check for fcm abnormal handle \a handle. */
+#define IS_FCM_HANDLE(handle) \
+( (ClkFcmHandleInterrupt == (handle)) || \
+ (ClkFcmHandleReset == (handle)))
+
+/*! Parameter validity check for debug clock division \a div. */
+#define IS_TPIUCLK_DIV_VALID(div) \
+( (ClkTpiuclkDiv1 == (div)) || \
+ (ClkTpiuclkDiv2 == (div)) || \
+ (ClkTpiuclkDiv4 == (div)))
+
+/*! Parameter validity check for output clock division \a div. */
+#define IS_OUTPUTCLK_DIV_VALID(div) \
+( (ClkOutputDiv1 == (div)) || \
+ ((ClkOutputDiv2 <= (div)) && \
+ (ClkOutputDiv128 >= (div))))
+
+/*! Parameter validity check for fcm measurement source division \a div. */
+#define IS_FCM_MEASRC_DIV_VALID(div) \
+( (ClkFcmMeaDiv1 == (div)) || \
+ (ClkFcmMeaDiv4 == (div)) || \
+ (ClkFcmMeaDiv8 == (div)) || \
+ (ClkFcmMeaDiv32 == (div)))
+
+/*! Parameter validity check for internal reference source division \a div. */
+#define IS_FCM_INTREF_DIV_VALID(div) \
+( (ClkFcmIntrefDiv32 == (div)) || \
+ (ClkFcmIntrefDiv128 == (div)) || \
+ (ClkFcmIntrefDiv1024 == (div)) || \
+ (ClkFcmIntrefDiv8192 == (div)))
+
+/*! Parameter validity check for system clock config \a cfg. */
+#define IS_SYSCLK_CONFIG_VALID(cfg) \
+( ((cfg)->enHclkDiv <= ((cfg)->enPclk1Div)) && \
+ ((cfg)->enHclkDiv <= ((cfg)->enPclk3Div)) && \
+ ((cfg)->enHclkDiv <= ((cfg)->enPclk4Div)) && \
+ ((cfg)->enPclk0Div <= ((cfg)->enPclk1Div)) && \
+ ((cfg)->enPclk0Div <= ((cfg)->enPclk3Div)) && \
+ (((cfg)->enPclk2Div-(cfg)->enPclk4Div == 3) || \
+ ((cfg)->enPclk2Div-(cfg)->enPclk4Div == 2) || \
+ ((cfg)->enPclk2Div-(cfg)->enPclk4Div == 1) || \
+ ((cfg)->enPclk2Div-(cfg)->enPclk4Div == 0) || \
+ ((cfg)->enPclk4Div-(cfg)->enPclk2Div == 1) || \
+ ((cfg)->enPclk4Div-(cfg)->enPclk2Div == 2) || \
+ ((cfg)->enPclk4Div-(cfg)->enPclk2Div == 3)))
+
+
+/*! Parameter validity check for clock status \a flag. */
+#define IS_CLK_FLAG(flag) \
+( (ClkFlagHRCRdy == (flag)) || \
+ (ClkFlagXTALRdy == (flag)) || \
+ (ClkFlagMPLLRdy == (flag)) || \
+ (ClkFlagUPLLRdy == (flag)) || \
+ (ClkFlagXTALStoppage == (flag)))
+/*! Parameter validity check for fcm status \a flag. */
+#define IS_FCM_FLAG(flag) \
+( (ClkFcmFlagOvf == (flag)) || \
+ (ClkFcmFlagMendf == (flag)) || \
+ (ClkFcmFlagErrf == (flag)))
+
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Configures the external high speed oscillator(XTAL).
+ **
+ ** \param [in] pstcXtalCfg The XTAL configures struct.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_XtalConfig(const stc_clk_xtal_cfg_t *pstcXtalCfg)
+{
+ if(NULL != pstcXtalCfg)
+ {
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_XTALCFGR_f.SUPDRV = pstcXtalCfg->enFastStartup;
+ M4_SYSREG->CMU_XTALCFGR_f.XTALMS = pstcXtalCfg->enMode;
+ M4_SYSREG->CMU_XTALCFGR_f.XTALDRV = pstcXtalCfg->enDrv;
+
+ DISABLE_CLOCK_REG_WRITE();
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the XTAL stable time.
+ **
+ ** \param [in] enXtalStb The XTAL stable time.
+ **
+ ** \retval None
+ **
+ ** \note One of the stable clock is 1/8 LRC clock.
+ **
+ ******************************************************************************/
+void CLK_XtalStbConfig(const en_clk_xtal_stb_cycle_t enXtalStb)
+{
+ DDL_ASSERT(IS_XTAL_STB_VALID(enXtalStb));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_XTALSTBCR_f.XTALSTB = enXtalStb;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the XTAL stoppage.
+ **
+ ** \param [in] pstcXtalStpCfg The XTAL stoppage configures struct.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_XtalStpConfig(const stc_clk_xtal_stp_cfg_t *pstcXtalStpCfg)
+{
+ if(NULL != pstcXtalStpCfg)
+ {
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_XTALSTDCR_f.XTALSTDE = pstcXtalStpCfg->enDetect;
+ M4_SYSREG->CMU_XTALSTDCR_f.XTALSTDRIS = pstcXtalStpCfg->enMode;
+ M4_SYSREG->CMU_XTALSTDCR_f.XTALSTDRE = pstcXtalStpCfg->enModeReset;
+ M4_SYSREG->CMU_XTALSTDCR_f.XTALSTDIE = pstcXtalStpCfg->enModeInt;
+
+ DISABLE_CLOCK_REG_WRITE();
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the XTAL.
+ **
+ ** \param [in] enNewState The new state of the XTAL.
+ ** \arg Enable Enable XTAL.
+ ** \arg Disable Disable XTAL.
+ **
+ ** \retval en_result_t
+ **
+ ** \note XTAL can not be stopped if it is used as system clock source or pll
+ ** clock source.
+ **
+ ******************************************************************************/
+en_result_t CLK_XtalCmd(en_functional_state_t enNewState)
+{
+ __IO uint32_t timeout = 0ul;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ if(Disable == enNewState)
+ {
+ if(ClkSysSrcXTAL == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ enRet = Error;
+ }
+ else if(ClkPllSrcXTAL == M4_SYSREG->CMU_PLLCFGR_f.PLLSRC)
+ {
+ if(0u == M4_SYSREG->CMU_PLLCR_f.MPLLOFF)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ M4_SYSREG->CMU_XTALCR_f.XTALSTP = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_XTALCR_f.XTALSTP = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_XTALCR_f.XTALSTP = 0u;
+ enRet = ErrorTimeout;
+ while (timeout < CLK_XTAL_TIMEOUT)
+ {
+ if (Set == CLK_GetFlagStatus(ClkFlagXTALRdy))
+ {
+ enRet = Ok;
+ break;
+ }
+ timeout++;
+ }
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the external low speed oscillator(XTAL32).
+ **
+ ** \param [in] pstcXtal32Cfg The XTAL32 configures struct.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_Xtal32Config(const stc_clk_xtal32_cfg_t *pstcXtal32Cfg)
+{
+ if(NULL != pstcXtal32Cfg)
+ {
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_XTAL32CFGR_f.XTAL32DRV = pstcXtal32Cfg->enDrv;
+ M4_SYSREG->CMU_XTAL32NFR_f.XTAL32NF = pstcXtal32Cfg->enFilterMode;
+
+ DISABLE_CLOCK_REG_WRITE();
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the XTAL32.
+ **
+ ** \param [in] enNewState The new state of the XTAL32.
+ ** \arg Enable Enable XTAL32.
+ ** \arg Disable Disable XTAL32.
+ **
+ ** \retval en_result_t
+ **
+ ** \note XTAL32 can not be stopped if it is used as system clock source.
+ **
+ ******************************************************************************/
+en_result_t CLK_Xtal32Cmd(en_functional_state_t enNewState)
+{
+ __IO uint32_t timeout = 0ul;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ if(Disable == enNewState)
+ {
+ if(ClkSysSrcXTAL32 == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ M4_SYSREG->CMU_XTAL32CR_f.XTAL32STP = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_XTAL32CR_f.XTAL32STP = 0u;
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_XTAL32_TIMEOUT);
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Trim the internal high speed oscillator(HRC).
+ **
+ ** \param [in] trimValue The trim value.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_HrcTrim(int8_t trimValue)
+{
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_HRCTRM = trimValue;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the HRC.
+ **
+ ** \param [in] enNewState The new state of the HRC.
+ ** \arg Enable Enable HRC.
+ ** \arg Disable Disable HRC.
+ **
+ ** \retval en_result_t
+ **
+ ** \note HRC can not be stopped if it is used as system clock source or pll
+ ** clock source.
+ **
+ ******************************************************************************/
+en_result_t CLK_HrcCmd(en_functional_state_t enNewState)
+{
+ __IO uint32_t timeout = 0ul;
+ en_result_t enRet = Ok;
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+ if(Disable == enNewState)
+ {
+ if(ClkSysSrcHRC == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ enRet = Error;
+ }
+ else if(ClkPllSrcHRC == M4_SYSREG->CMU_PLLCFGR_f.PLLSRC)
+ {
+ if(0u == M4_SYSREG->CMU_PLLCR_f.MPLLOFF)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ M4_SYSREG->CMU_HRCCR_f.HRCSTP = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_HRCCR_f.HRCSTP = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_HRCCR_f.HRCSTP = 0u;
+ enRet = ErrorTimeout;
+ while (timeout < CLK_HRC_TIMEOUT)
+ {
+ if (Set == CLK_GetFlagStatus(ClkFlagHRCRdy))
+ {
+ enRet = Ok;
+ break;
+ }
+ timeout++;
+ }
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Trim the internal middle speed oscillator(MRC).
+ **
+ ** \param [in] trimValue The trim value.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_MrcTrim(int8_t trimValue)
+{
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_MRCTRM = trimValue;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the MRC.
+ **
+ ** \param [in] enNewState The new state of the MRC.
+ ** \arg Enable Enable MRC.
+ ** \arg Disable Disable MRC.
+ **
+ ** \retval en_result_t
+ **
+ ** \note MRC can not be stopped if it is used as system clock source.
+ **
+ ******************************************************************************/
+en_result_t CLK_MrcCmd(en_functional_state_t enNewState)
+{
+ __IO uint32_t timeout = 0ul;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ if(Disable == enNewState)
+ {
+ if(ClkSysSrcMRC == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ M4_SYSREG->CMU_MRCCR_f.MRCSTP = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_MRCCR_f.MRCSTP = 0u;
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_MRC_TIMEOUT);
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Trim the internal low speed oscillator(LRC).
+ **
+ ** \param [in] trimValue The trim value.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_LrcTrim(int8_t trimValue)
+{
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_LRCTRM = trimValue;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the LRC.
+ **
+ ** \param [in] enNewState The new state of the LRC.
+ ** \arg Enable Enable LRC.
+ ** \arg Disable Disable LRC.
+ **
+ ** \retval en_result_t
+ **
+ ** \note LRC can not be stopped if it is used as system clock source.
+ **
+ ******************************************************************************/
+en_result_t CLK_LrcCmd(en_functional_state_t enNewState)
+{
+ __IO uint32_t timeout = 0ul;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ if(Disable == enNewState)
+ {
+ if(ClkSysSrcLRC == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ M4_SYSREG->CMU_LRCCR_f.LRCSTP = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_LRCCR_f.LRCSTP = 0u;
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_LRC_TIMEOUT);
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Select pll clock source.
+ **
+ ** \param [in] enPllSrc The pll clock source.
+ ** \arg ClkPllSrcXTAL Select XTAL as pll clock source.
+ ** \arg ClkPllSrcHRC Select HRC as pll clock source.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_SetPllSource(en_clk_pll_source_t enPllSrc)
+{
+ DDL_ASSERT(IS_PLL_SOURCE(enPllSrc));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_PLLCFGR_f.PLLSRC = enPllSrc;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the MPLL.
+ **
+ ** \param [in] pstcMpllCfg The MPLL configures struct.
+ **
+ ** \retval None
+ **
+ ** \note The pllsource/pllm is between 1MHz and 24MHz.
+ ** The pllsource/pllm*plln is between 240MHz and 480MHz.
+ ** The maximum of pllsource/pllm*plln/pllp is 200MHz.
+ **
+ ******************************************************************************/
+void CLK_MpllConfig(const stc_clk_mpll_cfg_t *pstcMpllCfg)
+{
+#ifdef __DEBUG
+ uint32_t vcoIn = 0ul;
+ uint32_t vcoOut = 0ul;
+#endif /* #ifdef __DEBUG */
+
+ if(NULL != pstcMpllCfg)
+ {
+ DDL_ASSERT(IS_PLL_DIV_VALID(pstcMpllCfg->PllpDiv));
+ DDL_ASSERT(IS_PLLQ_DIV_VALID(pstcMpllCfg->PllqDiv));
+ DDL_ASSERT(IS_PLL_DIV_VALID(pstcMpllCfg->PllrDiv));
+ DDL_ASSERT(IS_PLLN_VALID(pstcMpllCfg->plln));
+ DDL_ASSERT(IS_PLLM_VALID(pstcMpllCfg->pllmDiv));
+
+#ifdef __DEBUG
+ vcoIn = ((ClkPllSrcXTAL == M4_SYSREG->CMU_PLLCFGR_f.PLLSRC ?
+ XTAL_VALUE : HRC_VALUE) / pstcMpllCfg->pllmDiv);
+ vcoOut = vcoIn * pstcMpllCfg->plln;
+
+ DDL_ASSERT(IS_PLL_VCO_IN_VALID(vcoIn));
+ DDL_ASSERT(IS_PLL_VCO_OUT_VALID(vcoOut));
+#endif /* #ifdef __DEBUG */
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_PLLCFGR_f.MPLLP = pstcMpllCfg->PllpDiv - 1ul;
+ M4_SYSREG->CMU_PLLCFGR_f.MPLLQ = pstcMpllCfg->PllqDiv - 1ul;
+ M4_SYSREG->CMU_PLLCFGR_f.MPLLR = pstcMpllCfg->PllrDiv - 1ul;
+ M4_SYSREG->CMU_PLLCFGR_f.MPLLN = pstcMpllCfg->plln - 1ul;
+ M4_SYSREG->CMU_PLLCFGR_f.MPLLM = pstcMpllCfg->pllmDiv - 1ul;
+
+ DISABLE_CLOCK_REG_WRITE();
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the MPLL.
+ **
+ ** \param [in] enNewState The new state of the MPLL.
+ ** \arg Enable Enable MPLL.
+ ** \arg Disable Disable MPLL.
+ **
+ ** \retval en_result_t
+ **
+ ** \note MPLL can not be stopped if it is used as system clock source.
+ **
+ ******************************************************************************/
+en_result_t CLK_MpllCmd(en_functional_state_t enNewState)
+{
+ __IO uint32_t timeout = 0ul;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ if(Disable == enNewState)
+ {
+ if(CLKSysSrcMPLL == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ M4_SYSREG->CMU_PLLCR_f.MPLLOFF = 1u;
+ }
+ }
+ else
+ {
+ M4_SYSREG->CMU_PLLCR_f.MPLLOFF = 0u;
+ enRet = ErrorTimeout;
+ while (timeout < CLK_MPLL_TIMEOUT)
+ {
+ if (Set == CLK_GetFlagStatus(ClkFlagMPLLRdy))
+ {
+ enRet = Ok;
+ break;
+ }
+ timeout++;
+ }
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the UPLL.
+ **
+ ** \param [in] pstcUpllCfg The UPLL configures struct.
+ **
+ ** \retval None
+ **
+ ** \note The pllsource/pllm is between 1MHz and 24MHz.
+ ** The pllsource/pllm*plln is between 240MHz and 480MHz.
+ ** The maximum of pllsource/pllm*plln/pllp is 200MHz.
+ **
+ ******************************************************************************/
+void CLK_UpllConfig(const stc_clk_upll_cfg_t *pstcUpllCfg)
+{
+#ifdef __DEBUG
+ uint32_t vcoIn = 0ul;
+ uint32_t vcoOut = 0ul;
+#endif /* #ifdef __DEBUG */
+
+ if(NULL != pstcUpllCfg)
+ {
+ DDL_ASSERT(IS_PLL_DIV_VALID(pstcUpllCfg->PllpDiv));
+ DDL_ASSERT(IS_PLL_DIV_VALID(pstcUpllCfg->PllqDiv));
+ DDL_ASSERT(IS_PLL_DIV_VALID(pstcUpllCfg->PllrDiv));
+ DDL_ASSERT(IS_PLLN_VALID(pstcUpllCfg->plln));
+ DDL_ASSERT(IS_UPLLM_VALID(pstcUpllCfg->pllmDiv));
+
+#ifdef __DEBUG
+ vcoIn = ((ClkPllSrcXTAL == M4_SYSREG->CMU_PLLCFGR_f.PLLSRC ?
+ XTAL_VALUE : HRC_VALUE) / pstcUpllCfg->pllmDiv);
+ vcoOut = vcoIn * pstcUpllCfg->plln;
+
+ DDL_ASSERT(IS_PLL_VCO_IN_VALID(vcoIn));
+ DDL_ASSERT(IS_PLL_VCO_OUT_VALID(vcoOut));
+#endif /* #ifdef __DEBUG */
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_UPLLCFGR_f.UPLLP = pstcUpllCfg->PllpDiv - 1u;
+ M4_SYSREG->CMU_UPLLCFGR_f.UPLLQ = pstcUpllCfg->PllqDiv - 1u;
+ M4_SYSREG->CMU_UPLLCFGR_f.UPLLR = pstcUpllCfg->PllrDiv - 1u;
+ M4_SYSREG->CMU_UPLLCFGR_f.UPLLN = pstcUpllCfg->plln - 1u;
+ M4_SYSREG->CMU_UPLLCFGR_f.UPLLM = pstcUpllCfg->pllmDiv - 1u;
+
+ DISABLE_CLOCK_REG_WRITE();
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the UPLL.
+ **
+ ** \param [in] enNewState The new state of the UPLL.
+ ** \arg Enable Enable UPLL.
+ ** \arg Disable Disable UPLL.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t CLK_UpllCmd(en_functional_state_t enNewState)
+{
+ __IO uint32_t timeout;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_UPLLCR_f.UPLLOFF = ((Enable == enNewState) ? 0u : 1u);
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ if (Disable == enNewState)
+ {
+ timeout = 0ul;
+ while (Reset != CLK_GetFlagStatus(ClkFlagUPLLRdy))
+ {
+ timeout++;
+ if (timeout > CLK_UPLL_TIMEOUT)
+ {
+ return ErrorTimeout;
+ }
+ }
+ }
+ else
+ {
+ timeout = 0ul;
+ while (Set != CLK_GetFlagStatus(ClkFlagUPLLRdy))
+ {
+ timeout++;
+ if (timeout > CLK_UPLL_TIMEOUT)
+ {
+ return ErrorTimeout;
+ }
+ }
+ }
+
+ return Ok;
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Select system clock source.
+ **
+ ** \param [in] enTargetSysSrc The system clock source.
+ ** \arg ClkSysSrcHRC Select HRC as system clock source.
+ ** \arg ClkSysSrcMRC Select MRC as system clock source.
+ ** \arg ClkSysSrcLRC Select LRC as system clock source.
+ ** \arg ClkSysSrcXTAL Select XTAL as system clock source.
+ ** \arg ClkSysSrcXTAL32 Select XTAL32 as system clock source.
+ ** \arg CLKSysSrcMPLL Select MPLL as system clock source.
+ **
+ ** \retval None
+ **
+ ** \note Must close all of the fcg register before switch system clock source.
+ **
+ ******************************************************************************/
+void CLK_SetSysClkSource(en_clk_sys_source_t enTargetSysSrc)
+{
+ __IO uint32_t timeout = 0ul;
+ __IO uint32_t fcg0 = M4_MSTP->FCG0;
+ __IO uint32_t fcg1 = M4_MSTP->FCG1;
+ __IO uint32_t fcg2 = M4_MSTP->FCG2;
+ __IO uint32_t fcg3 = M4_MSTP->FCG3;
+
+ DDL_ASSERT(IS_SYSCLK_SOURCE(enTargetSysSrc));
+
+ ENABLE_FCG0_REG_WRITE();
+
+ /* Only current system clock source or target system clock source is MPLL
+ need to close fcg0~fcg3 and open fcg0~fcg3 during switch system clock source.
+ We need to backup fcg0~fcg3 before close them. */
+ if((CLKSysSrcMPLL == M4_SYSREG->CMU_CKSWR_f.CKSW) ||
+ (CLKSysSrcMPLL == enTargetSysSrc))
+ {
+ /* Close fcg0~fcg3. */
+ M4_MSTP->FCG0 = DEFAULT_FCG0;
+ M4_MSTP->FCG1 = DEFAULT_FCG1;
+ M4_MSTP->FCG2 = DEFAULT_FCG2;
+ M4_MSTP->FCG3 = DEFAULT_FCG3;
+
+ /* Wait stable after close fcg. */
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_FCG_STABLE);
+ }
+
+ /* Switch to target system clock source. */
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_CKSWR_f.CKSW = enTargetSysSrc;
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ timeout = 0ul;
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_SYSCLK_STABLE);
+
+ /* Open fcg0~fcg3. */
+ M4_MSTP->FCG0 = fcg0;
+ M4_MSTP->FCG1 = fcg1;
+ M4_MSTP->FCG2 = fcg2;
+ M4_MSTP->FCG3 = fcg3;
+
+ DISABLE_FCG0_REG_WRITE();
+
+ /* Wait stable after open fcg. */
+ timeout = 0ul;
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_FCG_STABLE);
+
+ SystemCoreClockUpdate();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get system clock source.
+ **
+ ** \param None
+ **
+ ** \retval The system clock source.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_clk_sys_source_t CLK_GetSysClkSource(void)
+{
+ return (en_clk_sys_source_t)M4_SYSREG->CMU_CKSWR_f.CKSW;
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Configures the division factor for hclk,exck,pclk0,pclk1,pclk2,pclk3,
+ ** pclk4 from system clock.
+ **
+ ** \param [in] pstcSysclkCfg The system clock configures struct.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_SysClkConfig(const stc_clk_sysclk_cfg_t *pstcSysclkCfg)
+{
+ __IO uint32_t timeout = 0ul;
+ __IO uint32_t fcg0 = M4_MSTP->FCG0;
+ __IO uint32_t fcg1 = M4_MSTP->FCG1;
+ __IO uint32_t fcg2 = M4_MSTP->FCG2;
+ __IO uint32_t fcg3 = M4_MSTP->FCG3;
+
+ ENABLE_FCG0_REG_WRITE();
+
+ if(NULL != pstcSysclkCfg)
+ {
+ DDL_ASSERT(IS_SYSCLK_CONFIG_VALID(pstcSysclkCfg));
+
+ /* Only current system clock source is MPLL need to close fcg0~fcg3 and
+ open fcg0~fcg3 during switch system clock division.
+ We need to backup fcg0~fcg3 before close them. */
+ if(CLKSysSrcMPLL == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ /* Close fcg0~fcg3. */
+ M4_MSTP->FCG0 = DEFAULT_FCG0;
+ M4_MSTP->FCG1 = DEFAULT_FCG1;
+ M4_MSTP->FCG2 = DEFAULT_FCG2;
+ M4_MSTP->FCG3 = DEFAULT_FCG3;
+
+ /* Wait stable after close fcg. */
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_FCG_STABLE);
+ }
+
+ /* Switch to target system clock division. */
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_SCFGR = ( (uint32_t)pstcSysclkCfg->enPclk0Div |
+ ((uint32_t)pstcSysclkCfg->enPclk1Div << 4u) |
+ ((uint32_t)pstcSysclkCfg->enPclk2Div << 8u) |
+ ((uint32_t)pstcSysclkCfg->enPclk3Div << 12u) |
+ ((uint32_t)pstcSysclkCfg->enPclk4Div << 16u) |
+ ((uint32_t)pstcSysclkCfg->enExclkDiv << 20u) |
+ ((uint32_t)pstcSysclkCfg->enHclkDiv << 24u) |
+ ((uint32_t)pstcSysclkCfg->enHclkDiv << 28u));
+
+ DISABLE_CLOCK_REG_WRITE();
+
+ timeout = 0ul;
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_SYSCLK_STABLE);
+
+ /* Open fcg0~fcg3. */
+ M4_MSTP->FCG0 = fcg0;
+ M4_MSTP->FCG1 = fcg1;
+ M4_MSTP->FCG2 = fcg2;
+ M4_MSTP->FCG3 = fcg3;
+
+ DISABLE_FCG0_REG_WRITE();
+
+ /* Wait stable after open fcg. */
+ timeout = 0ul;
+ do
+ {
+ timeout++;
+ }while(timeout < CLK_FCG_STABLE);
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Get clock frequency.
+ **
+ ** \param [in] pstcClkFreq The clock source struct.
+ **
+ ** \retval The clock frequency include system clock,hclk,exck,pclk0,pclk1,pclk2
+ ** pclk3,pclk4.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_GetClockFreq(stc_clk_freq_t *pstcClkFreq)
+{
+ uint32_t plln = 0u, pllp = 0u, pllm = 0u, pllsource = 0u;
+
+ if(NULL != pstcClkFreq)
+ {
+ /* Get system clock. */
+ switch(M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ case ClkSysSrcHRC:
+ /* HRC used as system clock. */
+ pstcClkFreq->sysclkFreq = HRC_VALUE;
+ break;
+ case ClkSysSrcMRC:
+ /* MRC used as system clock. */
+ pstcClkFreq->sysclkFreq = MRC_VALUE;
+ break;
+ case ClkSysSrcLRC:
+ /* LRC used as system clock. */
+ pstcClkFreq->sysclkFreq = LRC_VALUE;
+ break;
+ case ClkSysSrcXTAL:
+ /* XTAL used as system clock. */
+ pstcClkFreq->sysclkFreq = XTAL_VALUE;
+ break;
+ case ClkSysSrcXTAL32:
+ /* XTAL32 used as system clock. */
+ pstcClkFreq->sysclkFreq = XTAL32_VALUE;
+ break;
+ default:
+ /* MPLLP used as system clock. */
+ pllsource = M4_SYSREG->CMU_PLLCFGR_f.PLLSRC;
+ pllp = M4_SYSREG->CMU_PLLCFGR_f.MPLLP;
+ plln = M4_SYSREG->CMU_PLLCFGR_f.MPLLN;
+ pllm = M4_SYSREG->CMU_PLLCFGR_f.MPLLM;
+
+ /* PLLCLK = ((pllsrc / pllm) * plln) / pllp */
+ if (ClkPllSrcXTAL == pllsource)
+ {
+ pstcClkFreq->sysclkFreq = (XTAL_VALUE)/(pllm+1u)*(plln+1u)/(pllp+1u);
+ }
+ else if (ClkPllSrcHRC == pllsource)
+ {
+ pstcClkFreq->sysclkFreq = (HRC_VALUE)/(pllm+1u)*(plln+1u)/(pllp+1u);
+ }
+ else
+ {
+ //else
+ }
+ break;
+ }
+
+ /* Get hclk. */
+ pstcClkFreq->hclkFreq = pstcClkFreq->sysclkFreq >> M4_SYSREG->CMU_SCFGR_f.HCLKS;
+
+ /* Get exck. */
+ pstcClkFreq->exckFreq = pstcClkFreq->sysclkFreq >> M4_SYSREG->CMU_SCFGR_f.EXCKS;
+
+ /* Get pclk0. */
+ pstcClkFreq->pclk0Freq = pstcClkFreq->sysclkFreq >> M4_SYSREG->CMU_SCFGR_f.PCLK0S;
+
+ /* Get pclk1. */
+ pstcClkFreq->pclk1Freq = pstcClkFreq->sysclkFreq >> M4_SYSREG->CMU_SCFGR_f.PCLK1S;
+
+ /* Get pclk2. */
+ pstcClkFreq->pclk2Freq = pstcClkFreq->sysclkFreq >> M4_SYSREG->CMU_SCFGR_f.PCLK2S;
+
+ /* Get pclk3. */
+ pstcClkFreq->pclk3Freq = pstcClkFreq->sysclkFreq >> M4_SYSREG->CMU_SCFGR_f.PCLK3S;
+
+ /* Get pclk4. */
+ pstcClkFreq->pclk4Freq = pstcClkFreq->sysclkFreq >> M4_SYSREG->CMU_SCFGR_f.PCLK4S;
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get PLL clock frequency.
+ **
+ ** \param [in] pstcPllClkFreq The PLL clock source struct.
+ **
+ ** \retval The clock frequency include mpllp, mpllq, mpllr, upllp, upllq, upllr.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_GetPllClockFreq(stc_pll_clk_freq_t *pstcPllClkFreq)
+{
+ uint32_t pllsource;
+ uint32_t mplln = 0u, mpllp = 0u, mpllq = 0u, mpllr = 0u, mpllm = 0u;
+ uint32_t uplln = 0u, upllp = 0u, upllq = 0u, upllr = 0u, upllm = 0u;
+
+ /* Get pll clock source */
+ pllsource = M4_SYSREG->CMU_PLLCFGR_f.PLLSRC;
+
+ /* Get Mpll parameter value */
+ mpllp = M4_SYSREG->CMU_PLLCFGR_f.MPLLP;
+ mpllq = M4_SYSREG->CMU_PLLCFGR_f.MPLLQ;
+ mpllr = M4_SYSREG->CMU_PLLCFGR_f.MPLLR;
+ mplln = M4_SYSREG->CMU_PLLCFGR_f.MPLLN;
+ mpllm = M4_SYSREG->CMU_PLLCFGR_f.MPLLM;
+
+ /* Get Upll paramter value */
+ upllp = M4_SYSREG->CMU_UPLLCFGR_f.UPLLP;
+ upllq = M4_SYSREG->CMU_UPLLCFGR_f.UPLLQ;
+ upllr = M4_SYSREG->CMU_UPLLCFGR_f.UPLLR;
+ uplln = M4_SYSREG->CMU_UPLLCFGR_f.UPLLN;
+ upllm = M4_SYSREG->CMU_UPLLCFGR_f.UPLLM;
+
+ /* Get mpllp ,mpllr, mpllq, upllp, upllq, upllr clock frequency */
+ if (ClkPllSrcXTAL == pllsource)
+ {
+ pstcPllClkFreq->mpllp = (XTAL_VALUE)/(mpllm+1u)*(mplln+1u)/(mpllp+1u);
+ pstcPllClkFreq->mpllq = (XTAL_VALUE)/(mpllm+1u)*(mplln+1u)/(mpllq+1u);
+ pstcPllClkFreq->mpllr = (XTAL_VALUE)/(mpllm+1u)*(mplln+1u)/(mpllr+1u);
+ pstcPllClkFreq->upllp = (XTAL_VALUE)/(upllm+1u)*(uplln+1u)/(upllp+1u);
+ pstcPllClkFreq->upllq = (XTAL_VALUE)/(upllm+1u)*(uplln+1u)/(upllq+1u);
+ pstcPllClkFreq->upllr = (XTAL_VALUE)/(upllm+1u)*(uplln+1u)/(upllr+1u);
+ }
+ else if (ClkPllSrcHRC == pllsource)
+ {
+ pstcPllClkFreq->mpllp = (HRC_VALUE)/(mpllm+1u)*(mplln+1u)/(mpllp+1u);
+ pstcPllClkFreq->mpllq = (HRC_VALUE)/(mpllm+1u)*(mplln+1u)/(mpllq+1u);
+ pstcPllClkFreq->mpllr = (HRC_VALUE)/(mpllm+1u)*(mplln+1u)/(mpllr+1u);
+ pstcPllClkFreq->upllp = (HRC_VALUE)/(upllm+1u)*(uplln+1u)/(upllp+1u);
+ pstcPllClkFreq->upllq = (HRC_VALUE)/(upllm+1u)*(uplln+1u)/(upllq+1u);
+ pstcPllClkFreq->upllr = (HRC_VALUE)/(upllm+1u)*(uplln+1u)/(upllr+1u);
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Select usb clock source.
+ **
+ ** \param [in] enTargetUsbSrc The usb clock source.
+ ** \arg ClkUsbSrcSysDiv2 Select 1/2 system clock as usb clock source.
+ ** \arg ClkUsbSrcSysDiv3 Select 1/3 system clock as usb clock source.
+ ** \arg ClkUsbSrcSysDiv4 Select 1/4 system clock as usb clock source.
+ ** \arg ClkUsbSrcMpllp Select MPLLP as usb clock source.
+ ** \arg ClkUsbSrcMpllq Select MPLLQ as usb clock source.
+ ** \arg ClkUsbSrcMpllr Select MPLLR as usb clock source.
+ ** \arg ClkUsbSrcUpllp Select UPLLP as usb clock source.
+ ** \arg ClkUsbSrcUpllq Select UPLLQ as usb clock source.
+ ** \arg ClkUsbSrcUpllr Select UPLLR as usb clock source.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_SetUsbClkSource(en_clk_usb_source_t enTargetUsbSrc)
+{
+
+ DDL_ASSERT(IS_USBCLK_SOURCE(enTargetUsbSrc));
+
+ /* Switch to target usb clock source. */
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_UFSCKCFGR_f.USBCKS = enTargetUsbSrc;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Select peripheral(adc/trng) clock source.
+ **
+ ** \param [in] enTargetPeriSrc The peripheral(adc/trng) clock source.
+ ** \arg ClkPeriSrcPclk Select PCLK2 as adc analog clok, PCLK4 as adc digital clock. Select PCLK4 as trng clock.
+ ** \arg ClkPeriSrcMpllp Select MPLLP as peripheral(adc/trng) clock source.
+ ** \arg ClkPeriSrcMpllq Select MPLLQ as peripheral(adc/trng) clock source.
+ ** \arg ClkPeriSrcMpllr Select MPLLR as peripheral(adc/trng) clock source.
+ ** \arg ClkPeriSrcUpllp Select UPLLP as peripheral(adc/trng) clock source.
+ ** \arg ClkPeriSrcUpllq Select UPLLQ as peripheral(adc/trng) clock source.
+ ** \arg ClkPeriSrcUpllr Select UPLLR as peripheral(adc/trng) clock source.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void CLK_SetPeriClkSource(en_clk_peri_source_t enTargetPeriSrc)
+{
+ DDL_ASSERT(IS_PERICLK_SOURCE(enTargetPeriSrc));
+
+ ENABLE_CLOCK1_REG_WRITE();
+
+ /* Switch to target adc clock source. */
+ M4_SYSREG->CMU_PERICKSEL_f.PERICKSEL = enTargetPeriSrc;
+
+ DISABLE_CLOCK1_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Select I2S clock source.
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \arg M4_I2S1 I2s channel 1
+ ** \arg M4_I2S2 I2s channel 2
+ ** \arg M4_I2S3 I2s channel 3
+ ** \arg M4_I2S4 I2s channel 4
+ ** \param [in] enTargetPeriSrc The I2S clock source.
+ ** \arg ClkPeriSrcPclk Select PCLK3 as I2S clock source.
+ ** \arg ClkPeriSrcMpllp Select MPLLP as I2S clock source.
+ ** \arg ClkPeriSrcMpllq Select MPLLQ as I2S clock source.
+ ** \arg ClkPeriSrcMpllr Select MPLLR as I2S clock source.
+ ** \arg ClkPeriSrcUpllp Select UPLLP as I2S clock source.
+ ** \arg ClkPeriSrcUpllq Select UPLLQ as I2S clock source.
+ ** \arg ClkPeriSrcUpllr Select UPLLR as I2S clock source.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_SetI2sClkSource(const M4_I2S_TypeDef* pstcI2sReg, en_clk_peri_source_t enTargetPeriSrc)
+{
+ DDL_ASSERT(IS_PERICLK_SOURCE(enTargetPeriSrc));
+
+ ENABLE_CLOCK1_REG_WRITE();
+
+ if(M4_I2S1 == pstcI2sReg)
+ {
+ M4_SYSREG->CMU_I2SCKSEL_f.I2S1CKSEL = enTargetPeriSrc;
+ }
+ else if(M4_I2S2 == pstcI2sReg)
+ {
+ M4_SYSREG->CMU_I2SCKSEL_f.I2S2CKSEL = enTargetPeriSrc;
+ }
+ else if(M4_I2S3 == pstcI2sReg)
+ {
+ M4_SYSREG->CMU_I2SCKSEL_f.I2S3CKSEL = enTargetPeriSrc;
+ }
+ else if(M4_I2S4 == pstcI2sReg)
+ {
+ M4_SYSREG->CMU_I2SCKSEL_f.I2S4CKSEL = enTargetPeriSrc;
+ }
+ else
+ {
+ /* code */
+ }
+
+ DISABLE_CLOCK1_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get I2S clock source.
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \arg M4_I2S1 I2s channel 1
+ ** \arg M4_I2S2 I2s channel 2
+ ** \arg M4_I2S3 I2s channel 3
+ ** \arg M4_I2S4 I2s channel 4
+ **
+ ** \retval en_clk_peri_source_t The I2S clock source.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_clk_peri_source_t CLK_GetI2sClkSource(const M4_I2S_TypeDef* pstcI2sReg)
+{
+ en_clk_peri_source_t enI2sClkSource = ClkPeriSrcPclk;
+
+ if(M4_I2S1 == pstcI2sReg)
+ {
+ enI2sClkSource = (en_clk_peri_source_t)M4_SYSREG->CMU_I2SCKSEL_f.I2S1CKSEL;
+ }
+ else if(M4_I2S2 == pstcI2sReg)
+ {
+ enI2sClkSource = (en_clk_peri_source_t)M4_SYSREG->CMU_I2SCKSEL_f.I2S2CKSEL;
+ }
+ else if(M4_I2S3 == pstcI2sReg)
+ {
+ enI2sClkSource = (en_clk_peri_source_t)M4_SYSREG->CMU_I2SCKSEL_f.I2S3CKSEL;
+ }
+ else if(M4_I2S4 == pstcI2sReg)
+ {
+ enI2sClkSource = (en_clk_peri_source_t)M4_SYSREG->CMU_I2SCKSEL_f.I2S4CKSEL;
+ }
+ else
+ {
+ /* code */
+ }
+
+ return enI2sClkSource;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the debug clock.
+ **
+ ** \param [in] enTpiuDiv The division of debug clock from system
+ ** clock.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_TpiuClkConfig(const en_clk_tpiuclk_div_factor_t enTpiuDiv)
+{
+ DDL_ASSERT(IS_TPIUCLK_DIV_VALID(enTpiuDiv));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_TPIUCKCFGR_f.TPIUCKS = enTpiuDiv;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the debug clock.
+ **
+ ** \param [in] enNewState The new state of the debug clock.
+ ** \arg Enable Enable debug clock.
+ ** \arg Disable Disable debug clock.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_TpiuClkCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ M4_SYSREG->CMU_TPIUCKCFGR_f.TPIUCKOE = enNewState;
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configures the output clock.
+ **
+ ** \param [in] enCh The clock output channel.
+ ** \param [in] pstcOutputCfg The clock output configures struct.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_OutputClkConfig(en_clk_output_ch_t enCh, const stc_clk_output_cfg_t *pstcOutputCfg)
+{
+ if(NULL != pstcOutputCfg)
+ {
+ DDL_ASSERT(IS_OUTPUTCLK_CHANNEL(enCh));
+ DDL_ASSERT(IS_OUTPUTCLK_SOURCE(pstcOutputCfg->enOutputSrc));
+ DDL_ASSERT(IS_OUTPUTCLK_DIV_VALID(pstcOutputCfg->enOutputDiv));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ switch(enCh)
+ {
+ case ClkOutputCh1:
+ M4_SYSREG->CMU_MCO1CFGR_f.MCO1SEL = pstcOutputCfg->enOutputSrc;
+ M4_SYSREG->CMU_MCO1CFGR_f.MCO1DIV = pstcOutputCfg->enOutputDiv;
+ break;
+ case ClkOutputCh2:
+ M4_SYSREG->CMU_MCO2CFGR_f.MCO2SEL = pstcOutputCfg->enOutputSrc;
+ M4_SYSREG->CMU_MCO2CFGR_f.MCO2DIV = pstcOutputCfg->enOutputDiv;
+ break;
+ default:
+ break;
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the clock output.
+ **
+ ** \param [in] enCh The clock output channel.
+ ** \param [in] enNewState The new state of the clock output.
+ ** \arg Enable Enable clock output.
+ ** \arg Disable Disable clock output.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_OutputClkCmd(en_clk_output_ch_t enCh, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_CLOCK_REG_WRITE();
+
+ switch(enCh)
+ {
+ case ClkOutputCh1:
+ M4_SYSREG->CMU_MCO1CFGR_f.MCO1EN = enNewState;
+ break;
+ case ClkOutputCh2:
+ M4_SYSREG->CMU_MCO2CFGR_f.MCO2EN = enNewState;
+ break;
+ default:
+ break;
+ }
+
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Get the specified clock flag status.
+ **
+ ** \param [in] enClkFlag The specified clock flag.
+ ** \arg ClkFlagHRCRdy HRC is ready or not.
+ ** \arg ClkFlagXTALRdy XTAL is ready or not.
+ ** \arg ClkFlagMPLLRdy MPLL is ready or not.
+ ** \arg ClkFlagUPLLRdy UPLL is ready or not.
+ ** \arg ClkFlagXTALStoppage XTAL is detected stoppage or not.
+ **
+ ** \retval en_flag_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t CLK_GetFlagStatus(en_clk_flag_t enClkFlag)
+{
+ en_flag_status_t status;
+
+ DDL_ASSERT(IS_CLK_FLAG(enClkFlag));
+
+ switch(enClkFlag)
+ {
+ case ClkFlagHRCRdy:
+ status = ((1u == M4_SYSREG->CMU_OSCSTBSR_f.HRCSTBF) ? Set : Reset);
+ break;
+ case ClkFlagXTALRdy:
+ status = ((1u == M4_SYSREG->CMU_OSCSTBSR_f.XTALSTBF) ? Set : Reset);
+ break;
+ case ClkFlagMPLLRdy:
+ status = ((1u == M4_SYSREG->CMU_OSCSTBSR_f.MPLLSTBF) ? Set : Reset);
+ break;
+ case ClkFlagUPLLRdy:
+ status = ((1u == M4_SYSREG->CMU_OSCSTBSR_f.UPLLSTBF) ? Set : Reset);
+ break;
+ default:
+ status = ((1u == M4_SYSREG->CMU_XTALSTDSR_f.XTALSTDF) ? Set : Reset);
+ break;
+ }
+
+ return status;
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Configures the clock frequency measurement.
+ **
+ ** \param [in] pstcClkFcmCfg The clock frequency measurement configures
+ ** struct.
+ **
+ ** \retval None
+ **
+ ** \note Configures the window,measurement,reference and interrupt independently.
+ **
+ ******************************************************************************/
+void CLK_FcmConfig(const stc_clk_fcm_cfg_t *pstcClkFcmCfg)
+{
+ if(NULL != pstcClkFcmCfg)
+ {
+ /* Window config. */
+ if(pstcClkFcmCfg->pstcFcmWindowCfg)
+ {
+ /* Set window lower. */
+ M4_FCM->LVR = pstcClkFcmCfg->pstcFcmWindowCfg->windowLower;
+ /* Set window upper. */
+ M4_FCM->UVR = pstcClkFcmCfg->pstcFcmWindowCfg->windowUpper;
+ }
+
+ /* Measure config. */
+ if(pstcClkFcmCfg->pstcFcmMeaCfg)
+ {
+ DDL_ASSERT(IS_FCM_SOURCE(pstcClkFcmCfg->pstcFcmMeaCfg->enSrc));
+ DDL_ASSERT(IS_FCM_MEASRC_DIV_VALID(pstcClkFcmCfg->pstcFcmMeaCfg->enSrcDiv));
+
+ /* Measure source. */
+ M4_FCM->MCCR_f.MCKS = pstcClkFcmCfg->pstcFcmMeaCfg->enSrc;
+ /* Measure source division. */
+ M4_FCM->MCCR_f.MDIVS = pstcClkFcmCfg->pstcFcmMeaCfg->enSrcDiv;
+ }
+
+ /* Reference config. */
+ if(pstcClkFcmCfg->pstcFcmRefCfg)
+ {
+ DDL_ASSERT(IS_FCM_REF(pstcClkFcmCfg->pstcFcmRefCfg->enRefSel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcClkFcmCfg->pstcFcmRefCfg->enExtRef));
+ DDL_ASSERT(IS_FCM_SOURCE(pstcClkFcmCfg->pstcFcmRefCfg->enIntRefSrc));
+ DDL_ASSERT(IS_FCM_INTREF_DIV_VALID(pstcClkFcmCfg->pstcFcmRefCfg->enIntRefDiv));
+ DDL_ASSERT(IS_FCM_EDGE(pstcClkFcmCfg->pstcFcmRefCfg->enEdge));
+ DDL_ASSERT(IS_FCM_FILTER_CLK(pstcClkFcmCfg->pstcFcmRefCfg->enFilterClk));
+
+ M4_FCM->RCCR_f.INEXS = pstcClkFcmCfg->pstcFcmRefCfg->enRefSel;
+ M4_FCM->RCCR_f.EXREFE = pstcClkFcmCfg->pstcFcmRefCfg->enExtRef;
+ M4_FCM->RCCR_f.RCKS = pstcClkFcmCfg->pstcFcmRefCfg->enIntRefSrc;
+ M4_FCM->RCCR_f.RDIVS = pstcClkFcmCfg->pstcFcmRefCfg->enIntRefDiv;
+ M4_FCM->RCCR_f.EDGES = pstcClkFcmCfg->pstcFcmRefCfg->enEdge;
+ M4_FCM->RCCR_f.DNFS = pstcClkFcmCfg->pstcFcmRefCfg->enFilterClk;
+ }
+
+ /* Interrupt config. */
+ if(pstcClkFcmCfg->pstcFcmIntCfg)
+ {
+ DDL_ASSERT(IS_FCM_HANDLE(pstcClkFcmCfg->pstcFcmIntCfg->enHandleSel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcClkFcmCfg->pstcFcmIntCfg->enHandleReset));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcClkFcmCfg->pstcFcmIntCfg->enHandleInterrupt));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcClkFcmCfg->pstcFcmIntCfg->enOvfInterrupt));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcClkFcmCfg->pstcFcmIntCfg->enEndInterrupt));
+
+ M4_FCM->RIER_f.ERRINTRS = pstcClkFcmCfg->pstcFcmIntCfg->enHandleSel;
+ M4_FCM->RIER_f.ERRE = pstcClkFcmCfg->pstcFcmIntCfg->enHandleReset;
+ M4_FCM->RIER_f.ERRIE = pstcClkFcmCfg->pstcFcmIntCfg->enHandleInterrupt;
+ M4_FCM->RIER_f.MENDIE = pstcClkFcmCfg->pstcFcmIntCfg->enEndInterrupt;
+ M4_FCM->RIER_f.OVFIE = pstcClkFcmCfg->pstcFcmIntCfg->enOvfInterrupt;
+ }
+ }
+ else
+ {
+ /* code */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the clock frequency measurement.
+ **
+ ** \param [in] enNewState The new state of the clock frequency
+ ** measurement.
+ ** \arg Enable Enable clock frequency measurement.
+ ** \arg Disable Disable clock frequency measurement.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_FcmCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ M4_FCM->STR = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get fcm counter value.
+ **
+ ** \param None
+ **
+ ** \retval The fcm counter value.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint16_t CLK_GetFcmCounter(void)
+{
+ return (uint16_t)(M4_FCM->CNTR & 0xFFFFu);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the specified fcm flag status.
+ **
+ ** \param [in] enFcmFlag The specified fcm flag.
+ ** \arg ClkFcmFlagOvf The fcm counter overflow or not.
+ ** \arg ClkFcmFlagMendf The end of the measurement or not.
+ ** \arg ClkFcmFlagErrf Whether the frequency is abnormal or not.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t CLK_GetFcmFlag(en_clk_fcm_flag_t enFcmFlag)
+{
+ en_flag_status_t status = Reset;
+
+ DDL_ASSERT(IS_FCM_FLAG(enFcmFlag));
+
+ switch(enFcmFlag)
+ {
+ case ClkFcmFlagOvf:
+ status = (en_flag_status_t)M4_FCM->SR_f.OVF;
+ break;
+ case ClkFcmFlagMendf:
+ status = (en_flag_status_t)M4_FCM->SR_f.MENDF;
+ break;
+ case ClkFcmFlagErrf:
+ status = (en_flag_status_t)M4_FCM->SR_f.ERRF;
+ break;
+ default:
+ break;
+ }
+
+ return status;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the specified fcm flag status.
+ **
+ ** \param [in] enFcmFlag The specified fcm flag.
+ ** \arg ClkFcmFlagOvf Clear the fcm counter overflow flag.
+ ** \arg ClkFcmFlagMendf Clear the end of the measurement flag.
+ ** \arg ClkFcmFlagErrf Clear the frequency abnormal flag.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void CLK_ClearFcmFlag(en_clk_fcm_flag_t enFcmFlag)
+{
+ DDL_ASSERT(IS_FCM_FLAG(enFcmFlag));
+
+ switch(enFcmFlag)
+ {
+ case ClkFcmFlagOvf:
+ M4_FCM->CLR_f.OVFCLR = Set;
+ break;
+ case ClkFcmFlagMendf:
+ M4_FCM->CLR_f.MENDFCLR = Set;
+ break;
+ case ClkFcmFlagErrf:
+ M4_FCM->CLR_f.ERRFCLR = Set;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the XTAL error flag.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note The system clock should not be XTAL before call this function.
+ **
+ ******************************************************************************/
+void CLK_ClearXtalStdFlag(void)
+{
+ /* Enable register write. */
+ ENABLE_CLOCK_REG_WRITE();
+
+ if(Set == M4_SYSREG->CMU_XTALSTDSR_f.XTALSTDF)
+ {
+ /* Clear the XTAL STD flag */
+ M4_SYSREG->CMU_XTALSTDSR_f.XTALSTDF = Reset;
+ }
+
+ /* Disbale register write. */
+ DISABLE_CLOCK_REG_WRITE();
+}
+
+
+//@} // CmuGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_cmp.c b/lib/hc32f460/driver/src/hc32f460_cmp.c new file mode 100644 index 00000000..ef87ccd9 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_cmp.c @@ -0,0 +1,1042 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_cmp.c
+ **
+ ** A detailed description is available at
+ ** @link CmpGroup CMP @endlink
+ **
+ ** - 2018-10-22 CDT First version for Device Driver Library of CMP.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_cmp.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup CmpGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter valid check for CMP Instances. */
+#define IS_VALID_CMP(__CMPx__) \
+( (M4_CMP1 == (__CMPx__)) || \
+ (M4_CMP2 == (__CMPx__)) || \
+ (M4_CMP3 == (__CMPx__)))
+
+/*!< Parameter valid check for CMP function */
+#define IS_VALID_CMP_FUNCTION(x) \
+( (CmpOutput == (x)) || \
+ (CmpOutpuInv == (x)) || \
+ (CmpVcoutOutput == (x)))
+
+/*! Parameter validity check for edge sel. */
+#define IS_VALID_EDGESEL(x) \
+( (CmpNoneEdge == (x)) || \
+ (CmpBothEdge == (x)) || \
+ (CmpRisingEdge == (x)) || \
+ (CmpFaillingEdge == (x)))
+
+/*!< Parameter CMP FLT validity check for clock division. */
+#define IS_VALID_FLTCLK_DIVISION(x) \
+( (CmpNoneFlt == (x)) || \
+ (CmpFltPclk3Div1 == (x)) || \
+ (CmpFltPclk3Div2 == (x)) || \
+ (CmpFltPclk3Div4 == (x)) || \
+ (CmpFltPclk3Div8 == (x)) || \
+ (CmpFltPclk3Div16 == (x)) || \
+ (CmpFltPclk3Div32 == (x)) || \
+ (CmpFltPclk3Div64 == (x)))
+
+/*!< Parameter validity check for INP4 SEL. */
+#define IS_VALID_INP4SEL(x) \
+( (CmpInp4None == (x)) || \
+ (CmpInp4PGAO == (x)) || \
+ (CmpInp4PGAO_BP == (x)) || \
+ (CmpInp4CMP1_INP4 == (x)))
+
+/*!< Parameter validity check for INP INPUT SEL. */
+#define IS_VALID_INPSEL(x) \
+( (CmpInpNone == (x)) || \
+ (CmpInp1 == (x)) || \
+ (CmpInp2 == (x)) || \
+ (CmpInp3 == (x)) || \
+ (CmpInp4 == (x)) || \
+ (CmpInp1_Inp2 == (x)) || \
+ (CmpInp1_Inp3 == (x)) || \
+ (CmpInp2_Inp3 == (x)) || \
+ (CmpInp1_Inp4 == (x)) || \
+ (CmpInp2_Inp4 == (x)) || \
+ (CmpInp3_Inp4 == (x)) || \
+ (CmpInp1_Inp2_Inp3 == (x)) || \
+ (CmpInp1_Inp2_Inp4 == (x)) || \
+ (CmpInp1_Inp3_Inp4 == (x)) || \
+ (CmpInp2_Inp3_Inp4 == (x)) || \
+ (CmpInp1_Inp2_Inp3_Inp4 == (x)))
+
+/*!< Parameter validity check for INM INPUT SEL. */
+#define IS_VALID_INMSEL(x) \
+( (CmpInm1 == (x)) || \
+ (CmpInm2 == (x)) || \
+ (CmpInm3 == (x)) || \
+ (CmpInm4 == (x)) || \
+ (CmpInmNone == (x)))
+
+/*!< Parameter validity check for CMP_CR channel. */
+#define IS_VALID_CMP_CR_CH(x) \
+( (CmpDac1 == (x)) || \
+ (CmpDac2 == (x)))
+
+/*!< Parameter validity check for ADC internal reference voltage path. */
+#define IS_VALID_ADC_REF_VOLT_PATH(x) \
+( (CmpAdcRefVoltPathDac1 == (x)) || \
+ (CmpAdcRefVoltPathDac2 == (x)) || \
+ (CmpAdcRefVoltPathVref == (x)))
+
+/*!< RVADC Write Protection Key. */
+#define RVADC_WRITE_PROT_KEY (0x5500u)
+
+/*!< Timer4x ECER register address. */
+#define CMP_CR_DADRx(__DACx__) \
+( (CmpDac1 == (__DACx__)) ? &M4_CMP_CR->DADR1 : &M4_CMP_CR->DADR2)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initializes the specified CMP.
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] pstcInitCfg Pointer to CMP configure structure
+ ** \arg This parameter detail refer @ref stc_cmp_init_t
+ **
+ ** \retval Ok CMP is initialized normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - CMPx is invalid
+ ** - pstcInitCfg == NULL
+ **
+ ******************************************************************************/
+en_result_t CMP_Init(M4_CMP_TypeDef *CMPx, const stc_cmp_init_t *pstcInitCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx && pstcInitCfg pointer */
+ if ((IS_VALID_CMP(CMPx)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_EDGESEL(pstcInitCfg->enEdgeSel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpIntEN));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpInvEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpOutputEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpVcoutOutputEn));
+ DDL_ASSERT(IS_VALID_FLTCLK_DIVISION(pstcInitCfg->enFltClkDiv));
+
+ /* De-Initialize CMP */
+ CMPx->CTRL = (uint16_t)0x0000u;
+ CMPx->VLTSEL = (uint16_t)0x0000u;
+ CMPx->CVSSTB = (uint16_t)0x0005u;
+ CMPx->CVSPRD = (uint16_t)0x000Fu;
+
+ CMPx->CTRL_f.IEN = (uint16_t)pstcInitCfg->enCmpIntEN;
+ CMPx->CTRL_f.INV = (uint16_t)pstcInitCfg->enCmpInvEn;
+ CMPx->CTRL_f.EDGSL = (uint16_t)pstcInitCfg->enEdgeSel;
+ CMPx->CTRL_f.FLTSL = (uint16_t)pstcInitCfg->enFltClkDiv;
+ CMPx->CTRL_f.CMPOE = (uint16_t)pstcInitCfg->enCmpOutputEn;
+ CMPx->CTRL_f.OUTEN = (uint16_t)pstcInitCfg->enCmpVcoutOutputEn;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initialize CMP
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_DeInit(M4_CMP_TypeDef *CMPx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ CMPx->CTRL = (uint16_t)0x0000u;
+ CMPx->VLTSEL = (uint16_t)0x0000u;
+ CMPx->CVSSTB = (uint16_t)0x0005u;
+ CMPx->CVSPRD = (uint16_t)0x000Fu;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable CMP working
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enCmd The CMP function state
+ ** \arg Disable Disable CMP working
+ ** \arg Enable Enable CMP working
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_Cmd(M4_CMP_TypeDef *CMPx, en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ CMPx->CTRL_f.CMPON = (uint16_t)(enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable CMP interrupt request
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enCmd The CMP interrupt function state
+ ** \arg Disable Disable interrupt request
+ ** \arg Enable Enable interrupt request
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid.
+ **
+ ******************************************************************************/
+en_result_t CMP_IrqCmd(M4_CMP_TypeDef *CMPx, en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ CMPx->CTRL_f.IEN = (uint16_t)(enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set scan time(scan stable&&period)
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] u8ScanStable CMP scan stable value
+ ** \arg u8ScanStable < 16
+ ** \param [in] u8ScanPeriod CMP scan period value
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ** \note u8ScanStable && u8ScanPeriod value must meet following condition:
+ ** u8ScanPeriod > u8ScanStable + FLTSL_DIV*4 + 5
+ ** FLTSL_DIV is filter sample period division(refer CMPx->CTRL_f.FLTSL)
+ **
+ ******************************************************************************/
+en_result_t CMP_SetScanTime(M4_CMP_TypeDef *CMPx,
+ uint8_t u8ScanStable,
+ uint8_t u8ScanPeriod)
+{
+ uint16_t u16Flts;
+ uint16_t u16FltslDiv;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if ((!IS_VALID_CMP(CMPx)) || (u8ScanStable & 0xF0u))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ u16Flts = CMPx->CTRL_f.FLTSL;
+ u16FltslDiv = ((uint16_t)1u << (u16Flts - 1u));
+
+ if ((0u != u16Flts) &&
+ (u8ScanPeriod <= (u8ScanStable + u16FltslDiv * 4u + 5u)))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ CMPx->CVSSTB_f.STB = u8ScanStable;
+ CMPx->CVSPRD_f.PRD = u8ScanPeriod;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the specified CMP function.
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enFunc CMP function selection
+ ** \arg CmpVcoutOutput CMP Vcout output enable function
+ ** \arg CmpOutpuInv CMP output invert enable function
+ ** \arg CmpOutput CMP output enable function
+ ** \param [in] enCmd CMP functional state
+ ** \arg Enable Enable the specified CMP function
+ ** \arg Disable Disable the specified CMP function
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_FuncCmd(M4_CMP_TypeDef *CMPx,
+ en_cmp_func_t enFunc,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+ DDL_ASSERT(IS_VALID_CMP_FUNCTION(enFunc));
+
+ if (Enable == enCmd)
+ {
+ CMPx->CTRL |= (uint16_t)enFunc;
+ }
+ else
+ {
+ CMPx->CTRL &= (uint16_t)(~((uint16_t)enFunc));
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Start CMP scan
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval Ok Start successfully
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_StartScan(M4_CMP_TypeDef *CMPx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ CMPx->CTRL_f.CVSEN = (uint16_t)1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Stop CMP scan
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval Ok Stop successfully
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_StopScan(M4_CMP_TypeDef *CMPx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ CMPx->CTRL_f.CVSEN = (uint16_t)0u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set CMP filter sample clock division.
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enFltClkDiv The CMP filter sample clock division selection
+ ** \arg CmpNoneFlt Unuse filter
+ ** \arg CmpFltPclk3Div1 PCLK3/1
+ ** \arg CmpFltPclk3Div2 PCLK3/2
+ ** \arg CmpFltPclk3Div4 PCLK3/4
+ ** \arg CmpFltPclk3Div8 PCLK3/8
+ ** \arg CmpFltPclk3Div16 PCLK3/16
+ ** \arg CmpFltPclk3Div32 PCLK3/32
+ ** \arg CmpFltPclk3Div64 PCLK3/64
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_SetFilterClkDiv(M4_CMP_TypeDef *CMPx,
+ en_cmp_fltclk_div_t enFltClkDiv)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_FLTCLK_DIVISION(enFltClkDiv));
+ CMPx->CTRL_f.FLTSL = (uint16_t)enFltClkDiv;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get CMP filter sample clock division.
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval CmpNoneFlt Unuse filter
+ ** \retval CmpFltPclk3Div1 PCLK3/1
+ ** \retval CmpFltPclk3Div2 PCLK3/2
+ ** \retval CmpFltPclk3Div4 PCLK3/4
+ ** \retval CmpFltPclk3Div8 PCLK3/8
+ ** \retval CmpFltPclk3Div16 PCLK3/16
+ ** \retval CmpFltPclk3Div32 PCLK3/32
+ ** \retval CmpFltPclk3Div64 PCLK3/64
+ **
+ ******************************************************************************/
+en_cmp_fltclk_div_t CMP_GetFilterClkDiv(M4_CMP_TypeDef *CMPx)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP(CMPx));
+
+ return (en_cmp_fltclk_div_t)CMPx->CTRL_f.FLTSL;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set CMP detection edge selection.
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enEdgeSel The CMP detection edge selection
+ ** \arg CmpNoneEdge None edge detection
+ ** \arg CmpRisingEdge Rising edge detection
+ ** \arg CmpFaillingEdge Falling edge detection
+ ** \arg CmpBothEdge Falling or Rising edge detection
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_SetEdgeSel(M4_CMP_TypeDef *CMPx,
+ en_cmp_edge_sel_t enEdgeSel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_EDGESEL(enEdgeSel));
+ CMPx->CTRL_f.EDGSL = (uint16_t)enEdgeSel;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get CMP detection edge selection.
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval CmpNoneEdge None edge detection
+ ** \retval CmpRisingEdge Rising edge detection
+ ** \retval CmpFaillingEdge Falling edge detection
+ ** \retval CmpBothEdge Falling or Rising edge detection
+ **
+ ******************************************************************************/
+en_cmp_edge_sel_t CMP_GetEdgeSel(M4_CMP_TypeDef *CMPx)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP(CMPx));
+
+ return (en_cmp_edge_sel_t)CMPx->CTRL_f.EDGSL;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set CMP input sel
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] pstcInputSel The CMP input selection structure
+ ** \arg This parameter detail refer @ref stc_cmp_input_sel_t
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_InputSel(M4_CMP_TypeDef *CMPx,
+ const stc_cmp_input_sel_t *pstcInputSel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx && pstcInputSel pointer */
+ if ((IS_VALID_CMP(CMPx)) && (NULL != pstcInputSel))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_INMSEL(pstcInputSel->enInmSel));
+ DDL_ASSERT(IS_VALID_INPSEL(pstcInputSel->enInpSel));
+ DDL_ASSERT(IS_VALID_INP4SEL(pstcInputSel->enInp4Sel));
+
+ if ((CmpInp4PGAO == pstcInputSel->enInp4Sel) ||
+ (CmpInp4PGAO_BP == pstcInputSel->enInp4Sel))
+ {
+ if (M4_CMP3 != CMPx)
+ {
+ enRet = Ok;
+ }
+ }
+ else if (CmpInp4CMP1_INP4 == pstcInputSel->enInp4Sel)
+ {
+ if (M4_CMP1 == CMPx)
+ {
+ enRet = Ok;
+ }
+ }
+ else
+ {
+ enRet = Ok;
+ }
+
+ if (enRet == Ok)
+ {
+ CMPx->VLTSEL_f.CVSL = (uint16_t)pstcInputSel->enInpSel;
+ CMPx->VLTSEL_f.RVSL = (uint16_t)pstcInputSel->enInmSel;
+ CMPx->VLTSEL_f.C4SL = (uint16_t)pstcInputSel->enInp4Sel;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set CMP INP input selection
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enInputSel The INP input selection
+ ** \arg CmpInpNone None input
+ ** \arg CmpInp1 INP1 input
+ ** \arg CmpInp2 INP2 input
+ ** \arg CmpInp1_Inp2 INP1 INP2 input
+ ** \arg CmpInp3 INP3 input
+ ** \arg CmpInp1_Inp3 INP1 INP3 input
+ ** \arg CmpInp2_Inp3 INP2 INP3 input
+ ** \arg CmpInp1_Inp2_Inp3 INP1 INP2 INP3 input
+ ** \arg CmpInp4 INP4 input
+ ** \arg CmpInp1_Inp4 INP1 INP4 input
+ ** \arg CmpInp2_Inp4 INP2 INP4 input
+ ** \arg CmpInp1_Inp2_Inp4 INP1 INP2 INP4 input
+ ** \arg CmpInp3_Inp4 INP3 INP4 input
+ ** \arg CmpInp1_Inp3_Inp4 INP1 INP3 INP4 input
+ ** \arg CmpInp2_Inp3_Inp4 INP2 INP3 INP4 input
+ ** \arg CmpInp1_Inp2_Inp3_Inp4 INP1 INP2 INP3 INP4 input
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid
+ **
+ ******************************************************************************/
+en_result_t CMP_SetInp(M4_CMP_TypeDef *CMPx, en_cmp_inp_sel_t enInputSel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_INPSEL(enInputSel));
+ CMPx->VLTSEL_f.CVSL = (uint16_t)enInputSel;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set CMP INP input selection
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval CmpInpNone None input
+ ** \retval CmpInp1 INP1 input
+ ** \retval CmpInp2 INP2 input
+ ** \retval CmpInp1_Inp2 INP1 INP2 input
+ ** \retval CmpInp3 INP3 input
+ ** \retval CmpInp1_Inp3 INP1 INP3 input
+ ** \retval CmpInp2_Inp3 INP2 INP3 input
+ ** \retval CmpInp1_Inp2_Inp3 INP1 INP2 INP3 input
+ ** \retval CmpInp4 INP4 input
+ ** \retval CmpInp1_Inp4 INP1 INP4 input
+ ** \retval CmpInp2_Inp4 INP2 INP4 input
+ ** \retval CmpInp1_Inp2_Inp4 INP1 INP2 INP4 input
+ ** \retval CmpInp3_Inp4 INP3 INP4 input
+ ** \retval CmpInp1_Inp3_Inp4 INP1 INP3 INP4 input
+ ** \retval CmpInp2_Inp3_Inp4 INP2 INP3 INP4 input
+ ** \retval CmpInp1_Inp2_Inp3_Inp4 INP1 INP2 INP3 INP4 input
+ **
+ ******************************************************************************/
+en_cmp_inp_sel_t CMP_GetInp(M4_CMP_TypeDef *CMPx)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP(CMPx));
+
+ return (en_cmp_inp_sel_t)CMPx->VLTSEL_f.CVSL;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set CMP INM input selection
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enInputSel The INP input selection
+ ** \arg CmpInmNone None input
+ ** \arg CmpInm1 INM1 input
+ ** \arg CmpInm2 INM2 input
+ ** \arg CmpInm3 INM3 input
+ ** \arg CmpInm4 INM4 input
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid.
+ **
+ ******************************************************************************/
+en_result_t CMP_SetInm(M4_CMP_TypeDef *CMPx, en_cmp_inm_sel_t enInputSel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_INMSEL(enInputSel));
+ CMPx->VLTSEL_f.RVSL = (uint16_t)enInputSel;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get CMP INM input selection
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval CmpInmNone None input
+ ** \retval CmpInm1 INM1 input
+ ** \retval CmpInm2 INM2 input
+ ** \retval CmpInm3 INM3 input
+ ** \retval CmpInm4 INM4 input
+ **
+ ******************************************************************************/
+en_cmp_inm_sel_t CMP_GetInm(M4_CMP_TypeDef *CMPx)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP(CMPx));
+
+ return (en_cmp_inm_sel_t)CMPx->VLTSEL_f.RVSL;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set CMP INP4 input selection
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ ** \param [in] enInputSel The INP input selection
+ ** \arg CmpInp4None None input
+ ** \arg CmpInp4PGAO PGAO output
+ ** \arg CmpInp4PGAO_BP PGAO_BP output
+ ** \arg CmpInp4CMP1_INP4 CMP1_INP4
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter CMPx is invalid.
+ **
+ ** \note Inp4 Selection is valid only for M4_CMP1
+ ** and M4_CMP2.
+ **
+ ******************************************************************************/
+en_result_t CMP_SetInp4(M4_CMP_TypeDef *CMPx,en_cmp_inp4_sel_t enInputSel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameter */
+ DDL_ASSERT(M4_CMP3 != CMPx);
+ DDL_ASSERT(IS_VALID_INP4SEL(enInputSel));
+
+ /* Check CMPx pointer */
+ if (IS_VALID_CMP(CMPx))
+ {
+ CMPx->VLTSEL_f.C4SL = (uint16_t)enInputSel;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get CMP INP4 input selection
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval CmpInp4None None input
+ ** \retval CmpInp4PGAO PGAO output
+ ** \retval CmpInp4PGAO_BP PGAO_BP output
+ ** \retval CmpInp4CMP1_INP4 CMP1_INP4
+ **
+ ** \note Inp4 Selection is valid only for M4_CMP1
+ ** and M4_CMP2.
+ **
+ ******************************************************************************/
+en_cmp_inp4_sel_t CMP_GetInp4(M4_CMP_TypeDef *CMPx)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP(CMPx));
+
+ return (en_cmp_inp4_sel_t)CMPx->VLTSEL_f.C4SL;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get CMP output state
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval CmpOutputLow Compare output Low "0"
+ ** \retval CmpOutputHigh Compare output High "1"
+ **
+ ******************************************************************************/
+en_cmp_output_state_t CMP_GetOutputState(M4_CMP_TypeDef *CMPx)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP(CMPx));
+
+ return (en_cmp_output_state_t)(CMPx->OUTMON_f.OMON);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get CMP INP state
+ **
+ ** \param [in] CMPx Pointer to CMP instance register base
+ ** \arg M4_CMP1 CMP unit 1 instance register base
+ ** \arg M4_CMP2 CMP unit 2 instance register base
+ ** \arg M4_CMP3 CMP unit 3 instance register base
+ **
+ ** \retval CmpOutputLow Compare output Low "0"
+ ** \retval CmpOutputHigh Compare output High "1"
+ **
+ ******************************************************************************/
+en_cmp_inp_state_t CMP_GetInpState(M4_CMP_TypeDef *CMPx)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP(CMPx));
+
+ return (en_cmp_inp_state_t)(CMPx->OUTMON_f.CVST);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize CMP DAC
+ **
+ ** \param [in] enCh CMP DAC channel
+ ** \arg CmpDac1 CMP CR DAC channel: DAC1
+ ** \arg CmpDac2 CMP CR DAC channel: DAC2
+ ** \param [in] pstcInitCfg Pointer to CMP DAC configure structure
+ ** \arg This parameter detail refer @ref stc_cmp_dac_init_t
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enCh is invalid.
+ **
+ ******************************************************************************/
+en_result_t CMP_DAC_Init(en_cmp_dac_ch_t enCh,
+ const stc_cmp_dac_init_t *pstcInitCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((IS_VALID_CMP_CR_CH(enCh)) && (pstcInitCfg != NULL))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpDacEN));
+
+ M4_CMP_CR->DACR &= (uint16_t)(~(1ul << enCh)); /* Disable DAC */
+
+ *(__IO uint8_t *)CMP_CR_DADRx(enCh) = pstcInitCfg->u8DacData; /* Set DAC data */
+
+ if (Enable == pstcInitCfg->enCmpDacEN)
+ {
+ M4_CMP_CR->DACR |= (uint16_t)(1ul << enCh); /* Enable DAC */
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initialize CMP DAC
+ **
+ ** \param [in] enCh CMP DAC channel
+ ** \arg CmpDac1 CMP CR DAC channel: DAC1
+ ** \arg CmpDac2 CMP CR DAC channel: DAC2
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enCh is invalid.
+ **
+ ******************************************************************************/
+en_result_t CMP_DAC_DeInit(en_cmp_dac_ch_t enCh)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameter */
+ if (IS_VALID_CMP_CR_CH(enCh))
+ {
+ M4_CMP_CR->DACR &= (uint16_t)(~(1ul << enCh));
+ *(__IO uint8_t *)CMP_CR_DADRx(enCh) = 0u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable CMP DAC working
+ **
+ ** \param [in] enCh CMP DAC channel
+ ** \arg CmpDac1 CMP DAC channel: DAC1
+ ** \arg CmpDac2 CMP DAC channel: DAC2
+ ** \param [in] enCmd The CMP DAC function state
+ ** \arg Disable Disable CMP DAC working
+ ** \arg Enable Enable CMP DAC working
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enCh is invalid.
+ **
+ ******************************************************************************/
+en_result_t CMP_DAC_Cmd(en_cmp_dac_ch_t enCh, en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameter */
+ if (IS_VALID_CMP_CR_CH(enCh))
+ {
+ if(Enable == enCmd)
+ {
+ M4_CMP_CR->DACR |= (uint16_t)(1ul << enCh);
+ }
+ else
+ {
+ M4_CMP_CR->DACR &= (uint16_t)(~(1ul << enCh));
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set DAC data register value
+ **
+ ** \param [in] enCh CMP DAC channel
+ ** \arg CmpDac1 CMP CR DAC channel: DAC1
+ ** \arg CmpDac2 CMP CR DAC channel: DAC2
+ ** \param [in] u8DacData DAC data register value
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enCh is invalid.
+ **
+ ******************************************************************************/
+en_result_t CMP_DAC_SetData(en_cmp_dac_ch_t enCh, uint8_t u8DacData)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameter */
+ if (IS_VALID_CMP_CR_CH(enCh))
+ {
+ *(__IO uint8_t *)CMP_CR_DADRx(enCh) = u8DacData;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get DAC data register value
+ **
+ ** \param [in] enCh CMP DAC channel
+ ** \arg CmpDac1 CMP CR DAC channel: DAC1
+ ** \arg CmpDac2 CMP CR DAC channel: DAC2
+ **
+ ** \retval DAC data register value
+ **
+ ******************************************************************************/
+uint8_t CMP_DAC_GetData(en_cmp_dac_ch_t enCh)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_CMP_CR_CH(enCh));
+
+ return *(__IO uint8_t *)CMP_CR_DADRx(enCh);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set ADC internal reference voltage path
+ **
+ ** \param [in] enRefVoltPath ADC internal reference voltage path
+ ** \arg CmpAdcRefVoltPathDac1 ADC internal reference voltage path: DAC1
+ ** \arg CmpAdcRefVoltPathDac2 ADC internal reference voltage path: DAC2
+ ** \arg CmpAdcRefVoltPathVref ADC internal reference voltage path: VREF
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enRefVoltPath is invalid.
+ **
+ ******************************************************************************/
+en_result_t CMP_ADC_SetRefVoltPath(en_cmp_adc_int_ref_volt_path_t enRefVoltPath)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameter */
+ if (IS_VALID_ADC_REF_VOLT_PATH(enRefVoltPath))
+ {
+ M4_CMP_CR->RVADC = RVADC_WRITE_PROT_KEY; /* Release write protection */
+ M4_CMP_CR->RVADC = enRefVoltPath; /* Set reference voltage path */
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+//@} // CmpGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_crc.c b/lib/hc32f460/driver/src/hc32f460_crc.c new file mode 100644 index 00000000..c5d4f2be --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_crc.c @@ -0,0 +1,323 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_crc.c
+ **
+ ** A detailed description is available at
+ ** @link CrcGroup Crc description @endlink
+ **
+ ** - 2019-03-07 CDT First version for Device Driver Library of Crc.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_crc.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup CrcGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/* Definition of CRC16 data register. */
+#define M4_CRC16_DAT (*((__IO uint16_t *)&M4_CRC->DAT0))
+
+/* Definition of CRC16 checksum register. */
+#define M4_CRC16_RSLT (*((__IO uint16_t *)&M4_CRC->RESLT))
+
+/* Definition of CRC16 initial value register. */
+#define M4_CRC16_INIT (M4_CRC16_RSLT)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+static uint32_t CRC_ProcChecksum(uint32_t u32Checksum);
+static uint32_t CRC_ReverseBits(uint32_t u32Data);
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initialize the CRC.
+ **
+ ** \param [in] u32Config Bit[1]: CRC_SEL_16B or CRC_SEL_32B.
+ ** Bit[2]: CRC_REFIN_DISABLE or CRC_REFIN_ENABLE.
+ ** Bit[3]: CRC_REFOUT_DISABLE or CRC_REFOUT_ENABLE.
+ ** Bit[4]: CRC_XOROUT_DISABLE or CRC_XOROUT_ENABLE.
+ ** See the definitions for details.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void CRC_Init(uint32_t u32Config)
+{
+ u32Config &= CRC_CONFIG_MASK;
+
+ M4_CRC->CR = u32Config;
+}
+
+/**
+ *******************************************************************************
+ ** \brief CRC16 calculation.
+ **
+ ** \param [in] u16InitVal Initial value of CRC16.
+ **
+ ** \param [in] pu16Data Pointer to the buffer containing the data to be computed.
+ **
+ ** \param [in] u32Length Length of the buffer to be computed.
+ **
+ ** \retval 16-bit CRC checksum.
+ **
+ ******************************************************************************/
+uint16_t CRC_Calculate16B(uint16_t u16InitVal, const uint16_t *pu16Data, uint32_t u32Length)
+{
+ uint16_t u16Ret = 0u;
+ uint32_t u32Count;
+
+ if (NULL != pu16Data)
+ {
+ M4_CRC16_INIT = u16InitVal;
+
+ for (u32Count = 0u; u32Count < u32Length; u32Count++)
+ {
+ M4_CRC16_DAT = pu16Data[u32Count];
+ }
+
+ u16Ret = M4_CRC16_RSLT;
+ }
+
+ return u16Ret;
+}
+
+/**
+ *******************************************************************************
+ ** \brief CRC32 calculation.
+ **
+ ** \param [in] u32InitVal Initial value of CRC32.
+ **
+ ** \param [in] pu32Data Pointer to the buffer containing the data to be computed.
+ **
+ ** \param [in] u32Length Length of the buffer to be computed.
+ **
+ ** \retval 32-bit CRC checksum.
+ **
+ ******************************************************************************/
+uint32_t CRC_Calculate32B(uint32_t u32InitVal, const uint32_t *pu32Data, uint32_t u32Length)
+{
+ uint32_t u32Ret = 0u;
+ uint32_t u32Count;
+
+ M4_CRC->RESLT = u32InitVal;
+
+ if (NULL != pu32Data)
+ {
+ for (u32Count = 0u; u32Count < u32Length; u32Count++)
+ {
+ M4_CRC->DAT0 = pu32Data[u32Count];
+ }
+
+ u32Ret = M4_CRC->RESLT;
+ }
+
+ return u32Ret;
+}
+
+/**
+ *******************************************************************************
+ ** \brief CRC16 check.
+ **
+ ** \param [in] u16InitVal Initial value of CRC16.
+ **
+ ** \param [in] u16Checksum CRC16 checksum of the source data.
+ **
+ ** \param [in] pu16Data Pointer to the buffer containing the data to be checked.
+ **
+ ** \param [in] u32Length Length of the buffer to be checked.
+ **
+ ** \retval true CRC16 checks successfully.
+ ** \retval false CRC16 checks unsuccessfully.
+ **
+ ******************************************************************************/
+bool CRC_Check16B(uint16_t u16InitVal, uint16_t u16Checksum, const uint16_t *pu16Data, uint32_t u32Length)
+{
+ bool bRet = false;
+ uint32_t u32Count;
+ uint16_t u16CrcChecksum;
+
+ if (NULL != pu16Data)
+ {
+ u16CrcChecksum = (uint16_t)CRC_ProcChecksum((uint32_t)u16Checksum);
+ M4_CRC16_INIT = u16InitVal;
+
+ for (u32Count = 0u; u32Count < u32Length; u32Count++)
+ {
+ M4_CRC16_DAT = pu16Data[u32Count];
+ }
+
+ M4_CRC16_DAT = u16CrcChecksum;
+
+ if (bM4_CRC_RESLT_CRCFLAG_16)
+ {
+ bRet = true;
+ }
+ }
+
+ return bRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief CRC32 check.
+ **
+ ** \param [in] u32InitVal Initial value of CRC32.
+ **
+ ** \param [in] u32Checksum CRC32 checksum of the source data.
+ **
+ ** \param [in] pu32Data Pointer to the buffer containing the data to be checked.
+ **
+ ** \param [in] u32Length Length of the buffer to be checked.
+ **
+ ** \retval true CRC32 checks successfully.
+ ** \retval false CRC32 checks unsuccessfully.
+ **
+ ******************************************************************************/
+bool CRC_Check32B(uint32_t u32InitVal, uint32_t u32Checksum, const uint32_t *pu32Data, uint32_t u32Length)
+{
+ bool bRet = false;
+ uint32_t u32Count;
+ uint32_t u32CrcChecksum;
+
+ if (NULL != pu32Data)
+ {
+ u32CrcChecksum = CRC_ProcChecksum(u32Checksum);
+ M4_CRC->RESLT = u32InitVal;
+
+ for (u32Count = 0u; u32Count < u32Length; u32Count++)
+ {
+ M4_CRC->DAT0 = pu32Data[u32Count];
+ }
+
+ M4_CRC->DAT0 = u32CrcChecksum;
+
+ if (bM4_CRC_FLG_FLAG)
+ {
+ bRet = true;
+ }
+ }
+
+ return bRet;
+}
+
+/*******************************************************************************
+ * Function implementation - local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Processes the checksum of CRC.
+ **
+ ** \param [in] u32Checksum The checksum of CRC16 or CRC32.
+ **
+ ** \retval 32-bit new checksum will be used by CRC checking.
+ **
+ ******************************************************************************/
+static uint32_t CRC_ProcChecksum(uint32_t u32Checksum)
+{
+ uint8_t i;
+ uint8_t u8Size = 16u;
+ uint8_t u8Offset;
+ uint32_t u32Config;
+ uint32_t u32FinalChecksum;
+ uint32_t u32Temp;
+
+ u32Config = M4_CRC->CR;
+ u32FinalChecksum = u32Checksum;
+
+ if ((u32Config & CRC_SEL_32B) == CRC_SEL_32B)
+ {
+ u8Size = 32u;
+ }
+
+ if ((u32Config & CRC_REFOUT_ENABLE) == CRC_REFOUT_DISABLE)
+ {
+ /* Bits reversing. */
+ u32FinalChecksum = CRC_ReverseBits(u32Checksum);
+ if (u8Size == 16u)
+ {
+ u32FinalChecksum >>= 16u;
+ u32FinalChecksum &= 0xFFFFu;
+ }
+ }
+
+ if ((u32Config & CRC_XOROUT_ENABLE) == CRC_XOROUT_DISABLE)
+ {
+ /* Bits NOT. */
+ u32FinalChecksum = ~u32FinalChecksum;
+ }
+
+ if ((u32Config & CRC_REFIN_ENABLE) == CRC_REFIN_DISABLE)
+ {
+ u8Size /= 8u;
+ /* Bits reversing in bytes. */
+ for (i = 0u; i < u8Size; i++)
+ {
+ u8Offset = i * 8u;
+ u32Temp = (u32FinalChecksum >> u8Offset) & 0xFFul;
+ u32Temp = CRC_ReverseBits(u32Temp);
+ u32Temp = u32Temp >> (24u - u8Offset);
+ u32FinalChecksum &= ~((uint32_t)0xFF << u8Offset);
+ u32FinalChecksum |= u32Temp;
+ }
+ }
+
+ return u32FinalChecksum;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Reverse bits.
+ **
+ ** \param [in] u32Data The data to be reversed bits.
+ **
+ ** \retval 32-bit new data.
+ **
+ ******************************************************************************/
+static uint32_t CRC_ReverseBits(uint32_t u32Data)
+{
+ u32Data = (((u32Data & 0xAAAAAAAAul) >> 1u) | ((u32Data & 0x55555555ul) << 1u));
+ u32Data = (((u32Data & 0xCCCCCCCCul) >> 2u) | ((u32Data & 0x33333333ul) << 2u));
+ u32Data = (((u32Data & 0xF0F0F0F0ul) >> 4u) | ((u32Data & 0x0F0F0F0Ful) << 4u));
+ u32Data = (((u32Data & 0xFF00FF00ul) >> 8u) | ((u32Data & 0x00FF00FFul) << 8u));
+
+ return ((u32Data >> 16u) | (u32Data << 16u));
+}
+
+//@} // CrcGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_dcu.c b/lib/hc32f460/driver/src/hc32f460_dcu.c new file mode 100644 index 00000000..aaf7b25e --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_dcu.c @@ -0,0 +1,971 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_dcu.c
+ **
+ ** A detailed description is available at
+ ** @link DcuGroup DCU description @endlink
+ **
+ ** - 2018-10-15 CDT First version for Device Driver Library of DCU.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_dcu.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup DcuGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter valid check for DCU Instances. */
+#define IS_VALID_DCU(__DCUx__) \
+( (M4_DCU1 == (__DCUx__)) || \
+ (M4_DCU2 == (__DCUx__)) || \
+ (M4_DCU3 == (__DCUx__)) || \
+ (M4_DCU4 == (__DCUx__)))
+
+/*!< Parameter valid check for DCU DATA register. */
+#define IS_VALID_DCU_DATA_REG(x) \
+( (DcuRegisterData0 == (x)) || \
+ (DcuRegisterData1 == (x)) || \
+ (DcuRegisterData2 == (x)))
+
+/*!< Parameter valid check for DCU operation mode. */
+#define IS_VALID_DCU_OPERATION(x) \
+( (DcuOpAdd == (x)) || \
+ (DcuOpSub == (x)) || \
+ (DcuInvalid == (x)) || \
+ (DcuOpCompare == (x)) || \
+ (DcuHwTrigOpAdd == (x)) || \
+ (DcuHwTrigOpSub == (x)))
+
+/*!< Parameter valid check for DCU data size. */
+#define IS_VALID_DCU_DATAZ_SIZE(x) \
+( (DcuDataBit8 == (x)) || \
+ (DcuDataBit16 == (x)) || \
+ (DcuDataBit32 == (x)))
+
+/*!< Parameter valid check for DCU compare trigger mode type. */
+#define IS_VALID_DCU_CMP_TRIG_MODE(x) \
+( (DcuCmpTrigbyData0 == (x)) || \
+ (DcuCmpTrigbyData012 == (x)))
+
+/*!< Parameter valid check for DCU interrupt. */
+#define IS_VALID_DCU_INT(x) \
+( (DcuIntOp == (x)) || \
+ (DcuIntLs2 == (x)) || \
+ (DcuIntEq2 == (x)) || \
+ (DcuIntGt2 == (x)) || \
+ (DcuIntLs1 == (x)) || \
+ (DcuIntEq1 == (x)) || \
+ (DcuIntGt1 == (x)))
+
+/*!< Parameter valid check for DCU interrupt mode. */
+#define IS_VALID_DCU_INT_WIN_MODE(x) \
+( (DcuIntInvalid == (x)) || \
+ (DcuWinIntInvalid == (x)) || \
+ (DcuInsideWinCmpInt == (x)) || \
+ (DcuOutsideWinCmpInt == (x)))
+
+/*!< Parameter valid check for external trigger event. */
+#define IS_VALID_TRG_SRC_EVENT(x) \
+( (((x) >= EVT_PORT_EIRQ0) && ((x) <= EVT_PORT_EIRQ15)) || \
+ (((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
+ (((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
+ (((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
+ (((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
+ (((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
+ (((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
+ (((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
+ (((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
+ (((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
+ (((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
+ (((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
+ (((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
+ (((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
+ (((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
+ (((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
+ (((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
+ (((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
+ (((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
+ (((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
+ (((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
+ (((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
+ (((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
+ (((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
+ (((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
+ (((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
+ ((x) == EVT_WDT_REFUDF) || \
+ (((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
+ (((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
+ (((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)) || \
+ ((x) == EVT_MAX))
+
+/*! Parameter valid check for DCU common trigger. */
+#define IS_DCU_COM_TRIGGER(x) \
+( ((x) == DcuComTrigger_1) || \
+ ((x) == DcuComTrigger_2) || \
+ ((x) == DcuComTrigger_1_2))
+
+/*!< Get the specified DATA register address of the specified DCU unit */
+#define DCU_DATAx(__DCUx__, __DATAx__) ((uint32_t)(&(__DCUx__)->DATA0) + ((uint32_t)(__DATAx__)) * 4u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+static __IO uint32_t* DCU_TRGSELx(const M4_DCU_TypeDef *DCUx);
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initializes a DCU.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] pstcInitCfg Pointer to DCU configure structure
+ ** \arg This parameter detail refer @ref stc_dcu_init_t
+ **
+ ** \retval Ok DCU is initialized normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - DCUx is invalid
+ ** - pstcInitCfg == NULL
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t DCU_Init(M4_DCU_TypeDef *DCUx, const stc_dcu_init_t *pstcInitCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx && pstcInitCfg pointer */
+ if ((IS_VALID_DCU(DCUx)) && (NULL != pstcInitCfg))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enIntCmd));
+ DDL_ASSERT(IS_VALID_DCU_OPERATION(pstcInitCfg->enOperation));
+ DDL_ASSERT(IS_VALID_DCU_DATAZ_SIZE(pstcInitCfg->enDataSize));
+ DDL_ASSERT(IS_VALID_DCU_INT_WIN_MODE(pstcInitCfg->enIntWinMode));
+ DDL_ASSERT(IS_VALID_DCU_CMP_TRIG_MODE(pstcInitCfg->enCmpTriggerMode));
+
+ /* De-initialize dcu register value */
+ DCUx->CTL = 0ul;
+ DCUx->INTSEL = 0ul;
+ DCUx->FLAGCLR = 0x7Ful;
+
+ /* Set dcu operation mode */
+ DCUx->CTL_f.MODE = (uint32_t)pstcInitCfg->enOperation;
+
+ /* Set dcu data sieze */
+ DCUx->CTL_f.DATASIZE = (uint32_t)pstcInitCfg->enDataSize;
+
+ /* Set dcu compare trigger mode */
+ DCUx->CTL_f.COMP_TRG = (uint32_t)pstcInitCfg->enCmpTriggerMode;
+
+ /* Set dcu interrupt window mode */
+ DCUx->INTSEL_f.INT_WIN = (uint32_t)pstcInitCfg->enIntWinMode;
+
+ DCUx->INTSEL = pstcInitCfg->u32IntSel;
+ DCUx->CTL_f.INTEN = (uint32_t)(pstcInitCfg->enIntCmd);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initializes a DCU.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ **
+ ** \retval Ok De-Initialized successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_DeInit(M4_DCU_TypeDef *DCUx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO uint32_t *TRGSELx = DCU_TRGSELx(DCUx);
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* De-initialize dcu register value */
+ DCUx->CTL = 0u;
+ DCUx->INTSEL = 0u;
+ DCUx->FLAGCLR = 0x7Fu;
+ *TRGSELx = EVT_MAX;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set DCU operation mode.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enMode DCU operation mode
+ ** \arg DcuInvalid Invalid
+ ** \arg DcuOpAdd Operation: Add
+ ** \arg DcuOpSub Operation: Sub
+ ** \arg DcuHwTrigOpAdd Operation: Hardware trigger Add
+ ** \arg DcuHwTrigOpSub Operation: Hardware trigger Sub
+ ** \arg DcuOpCompare Operation: Compare
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_SetOperationMode(M4_DCU_TypeDef *DCUx,
+ en_dcu_operation_mode_t enMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_OPERATION(enMode));
+
+ DCUx->CTL_f.MODE = (uint32_t)enMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get DCU operation mode.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ **
+ ** \retval DcuInvalid Invalid
+ ** \retval DcuOpAdd Operation: Add
+ ** \retval DcuOpSub Operation: Sub
+ ** \retval DcuHwTrigOpAdd Operation: Hardware trigger Add
+ ** \retval DcuHwTrigOpSub Operation: Hardware trigger Sub
+ ** \retval DcuOpCompare Operation: Compare
+ **
+ ******************************************************************************/
+en_dcu_operation_mode_t DCU_GetOperationMode(M4_DCU_TypeDef *DCUx)
+{
+ /* Check for DCUx pointer */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+
+ return (en_dcu_operation_mode_t)DCUx->CTL_f.MODE;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set DCU data size.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enSize DCU data size
+ ** \arg DcuDataBit8 8 bit
+ ** \arg DcuDataBit16 16 bit
+ ** \arg DcuDataBit32 32 bit
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_SetDataSize(M4_DCU_TypeDef *DCUx, en_dcu_data_size_t enSize)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_DATAZ_SIZE(enSize));
+
+ DCUx->CTL_f.DATASIZE = (uint32_t)enSize;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get DCU data size.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ **
+ ** \retval DcuDataBit8 8 bit
+ ** \retval DcuDataBit16 16 bit
+ ** \retval DcuDataBit32 32 bit
+ **
+ ******************************************************************************/
+en_dcu_data_size_t DCU_GetDataSize(M4_DCU_TypeDef *DCUx)
+{
+ /* Check for DCUx pointer */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+
+ return (en_dcu_data_size_t)(DCUx->CTL_f.DATASIZE);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set DCU interrup window.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enIntWinMode Interrupt window mode
+ ** \arg DcuIntInvalid DCU don't occur interrupt
+ ** \arg DcuWinIntInvalid DCU window interrupt is invalid.
+ ** \arg DcuInsideWinCmpInt DCU occur interrupt when DATA2 <= DATA0 <= DATA2
+ ** \arg DcuOutsideWinCmpInt DCU occur interrupt when DATA0 > DATA1 or DATA0 < DATA2
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_SetIntWinMode(M4_DCU_TypeDef *DCUx,
+ en_dcu_int_win_mode_t enIntWinMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_INT_WIN_MODE(enIntWinMode));
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ DCUx->INTSEL_f.INT_WIN = (uint32_t)enIntWinMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get DCU interrup window.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ **
+ ** \retval DcuIntInvalid DCU don't occur interrupt
+ ** \retval DcuWinIntInvalid DCU window interrupt is invalid.
+ ** \retval DcuInsideWinCmpInt DCU occur interrupt when DATA2 <= DATA0 <= DATA2
+ ** \retval DcuOutsideWinCmpInt DCU occur interrupt when DATA0 > DATA1 or DATA0 < DATA2
+ **
+ ******************************************************************************/
+en_dcu_int_win_mode_t DCU_GetIntWinMode(M4_DCU_TypeDef *DCUx)
+{
+ /* Check for DCUx pointer */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+
+ return (en_dcu_int_win_mode_t)(DCUx->INTSEL_f.INT_WIN);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set DCU compare trigger mode.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enTriggerMode DCU compare trigger mode
+ ** \arg DcuCmpTrigbyData0 DCU compare triggered by DATA0
+ ** \arg DcuCmpTrigbyData012 DCU compare triggered by DATA0 or DATA1 or DATA2
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_SetCmpTriggerMode(M4_DCU_TypeDef *DCUx,
+ en_dcu_cmp_trigger_mode_t enTriggerMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_CMP_TRIG_MODE(enTriggerMode));
+
+ DCUx->CTL_f.COMP_TRG = (uint32_t)enTriggerMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get DCU compare trigger mode.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ **
+ ** \retval DcuCmpTrigbyData0 DCU compare triggered by DATA0
+ ** \retval DcuCmpTrigbyData012 DCU compare triggered by DATA0 or DATA1 or DATA2
+ **
+ ******************************************************************************/
+en_dcu_cmp_trigger_mode_t DCU_GetCmpTriggerMode(M4_DCU_TypeDef *DCUx)
+{
+ /* Check for DCUx pointer */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+
+ return (en_dcu_cmp_trigger_mode_t)(DCUx->CTL_f.COMP_TRG);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable DCU interrupt.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enCmd DCU interrupt state
+ ** \arg Enable Enable the DCU interrupt function
+ ** \arg Disable Disable the DCU interrupt function
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_IrqCmd(M4_DCU_TypeDef *DCUx, en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ DCUx->CTL_f.INTEN = (uint32_t)(enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the specified DCU flag
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enFlag The specified DCU flag
+ ** \arg DcuIntOp DCU overflow or underflow
+ ** \arg DcuIntLs2 DCU DATA0 < DATA2
+ ** \arg DcuIntEq2 DCU DATA0 = DATA2
+ ** \arg DcuIntGt2 DCU DATA0 > DATA2
+ ** \arg DcuIntLs1 DCU DATA0 < DATA1
+ ** \arg DcuIntEq1 DCU DATA0 = DATA1
+ ** \arg DcuIntGt1 DCU DATA0 > DATA1
+ **
+ ** \retval Set Flag is set.
+ ** \retval Reset Flag is reset or enStatus is invalid.
+ **
+ ******************************************************************************/
+en_flag_status_t DCU_GetIrqFlag(M4_DCU_TypeDef *DCUx, en_dcu_flag_t enFlag)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+ DDL_ASSERT(IS_VALID_DCU_INT(enFlag));
+
+ return ((DCUx->FLAG & enFlag) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the specified DCU flag
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enFlag the specified DCU flag
+ ** \arg DcuIntOp DCU overflow or underflow
+ ** \arg DcuIntLs2 DCU DATA0 < DATA2
+ ** \arg DcuIntEq2 DCU DATA0 = DATA2
+ ** \arg DcuIntGt2 DCU DATA0 > DATA2
+ ** \arg DcuIntLs1 DCU DATA0 < DATA1
+ ** \arg DcuIntEq1 DCU DATA0 = DATA1
+ ** \arg DcuIntGt1 DCU DATA0 > DATA1
+ **
+ ** \retval Ok Clear flag successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_ClearIrqFlag(M4_DCU_TypeDef *DCUx, en_dcu_flag_t enFlag)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_INT(enFlag));
+ DCUx->FLAGCLR = (uint32_t)enFlag;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable DCU interrupt.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enIntSel DCU interrupt selection
+ ** \arg DcuIntOp DCU overflow or underflow
+ ** \arg DcuIntLs2 DCU DATA0 < DATA2
+ ** \arg DcuIntEq2 DCU DATA0 = DATA2
+ ** \arg DcuIntGt2 DCU DATA0 > DATA2
+ ** \arg DcuIntLs1 DCU DATA0 < DATA1
+ ** \arg DcuIntEq1 DCU DATA0 = DATA1
+ ** \arg DcuIntGt1 DCU DATA0 > DATA1
+ ** \param [in] enCmd DCU interrupt functional state
+ ** \arg Enable Enable the specified DCU interrupt function
+ ** \arg Disable Disable the specified DCU interrupt function
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - DCUx is invalid
+ ** - enIntSel is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_IrqSelCmd(M4_DCU_TypeDef *DCUx,
+ en_dcu_int_sel_t enIntSel,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_INT(enIntSel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ enRet = Ok;
+ switch(enIntSel)
+ {
+ case DcuIntOp:
+ DCUx->INTSEL_f.INT_OP = (uint32_t)enCmd;
+ break;
+ case DcuIntLs2:
+ DCUx->INTSEL_f.INT_LS2 = (uint32_t)enCmd;
+ break;
+ case DcuIntEq2:
+ DCUx->INTSEL_f.INT_EQ2 = (uint32_t)enCmd;
+ break;
+ case DcuIntGt2:
+ DCUx->INTSEL_f.INT_GT2 = (uint32_t)enCmd;
+ break;
+ case DcuIntLs1:
+ DCUx->INTSEL_f.INT_LS1 = (uint32_t)enCmd;
+ break;
+ case DcuIntEq1:
+ DCUx->INTSEL_f.INT_EQ1 = (uint32_t)enCmd;
+ break;
+ case DcuIntGt1:
+ DCUx->INTSEL_f.INT_GT1 = (uint32_t)enCmd;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read DCU register DATAx
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enDataReg The specified DATA register.
+ ** \arg DcuRegisterData0 DCU register DATA0
+ ** \arg DcuRegisterData1 DCU register DATA1
+ ** \arg DcuRegisterData2 DCU register DATA2
+ **
+ ** \retval DCU register DATAx value
+ **
+ ******************************************************************************/
+uint8_t DCU_ReadDataByte(M4_DCU_TypeDef *DCUx,
+ en_dcu_data_register_t enDataReg)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+ DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
+
+ return *(uint8_t *)DCU_DATAx(DCUx, enDataReg);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write DCU register DATAx
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enDataReg The specified DATA register.
+ ** \arg DcuRegisterData0 DCU register DATA0
+ ** \arg DcuRegisterData1 DCU register DATA1
+ ** \arg DcuRegisterData2 DCU register DATA2
+ ** \param [in] u8Data The data will be written.
+ **
+ ** \retval Ok Write successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_WriteDataByte(M4_DCU_TypeDef *DCUx,
+ en_dcu_data_register_t enDataReg,
+ uint8_t u8Data)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
+
+ *(uint8_t *)DCU_DATAx(DCUx, enDataReg) = u8Data;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read DCU register DATAx
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enDataReg The specified DATA register.
+ ** \arg DcuRegisterData0 DCU register DATA0
+ ** \arg DcuRegisterData1 DCU register DATA1
+ ** \arg DcuRegisterData2 DCU register DATA2
+ **
+ ** \retval DCU register DATAx value
+ **
+ ******************************************************************************/
+uint16_t DCU_ReadDataHalfWord(M4_DCU_TypeDef *DCUx,
+ en_dcu_data_register_t enDataReg)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+ DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
+
+ return *(uint16_t *)DCU_DATAx(DCUx, enDataReg);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write DCU register DATAx
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enDataReg The specified DATA register.
+ ** \arg DcuRegisterData0 DCU register DATA0
+ ** \arg DcuRegisterData1 DCU register DATA1
+ ** \arg DcuRegisterData2 DCU register DATA2
+ ** \param [in] u16Data The data will be written.
+ **
+ ** \retval Ok Write successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_WriteDataHalfWord(M4_DCU_TypeDef *DCUx,
+ en_dcu_data_register_t enDataReg,
+ uint16_t u16Data)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
+
+ *(uint16_t *)DCU_DATAx(DCUx, enDataReg) = u16Data;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read DCU register DATAx
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enDataReg The specified DATA register.
+ ** \arg DcuRegisterData0 DCU register DATA0
+ ** \arg DcuRegisterData1 DCU register DATA1
+ ** \arg DcuRegisterData2 DCU register DATA2
+ **
+ ** \retval DCU register DATAx value
+ **
+ ******************************************************************************/
+uint32_t DCU_ReadDataWord(M4_DCU_TypeDef *DCUx,
+ en_dcu_data_register_t enDataReg)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU(DCUx));
+ DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
+
+ return *(uint32_t *)DCU_DATAx(DCUx, enDataReg);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write DCU register DATAx
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enDataReg The specified DATA register.
+ ** \arg DcuRegisterData0 DCU register DATA0
+ ** \arg DcuRegisterData1 DCU register DATA1
+ ** \arg DcuRegisterData2 DCU register DATA2
+ ** \param [in] u32Data The data will be written.
+ **
+ ** \retval Ok Write successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_WriteDataWord(M4_DCU_TypeDef *DCUx,
+ en_dcu_data_register_t enDataReg,
+ uint32_t u32Data)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for DCUx pointer */
+ if (IS_VALID_DCU(DCUx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
+
+ *(uint32_t *)DCU_DATAx(DCUx, enDataReg) = u32Data;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set DCU trigger source number
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enTriggerSrc The trigger source.
+ ** \arg This parameter can be any value of @ref en_event_src_t
+ **
+ ** \retval Ok Write successfully.
+ ** \retval ErrorInvalidParameter DCUx is invalid
+ **
+ ******************************************************************************/
+en_result_t DCU_SetTriggerSrc(M4_DCU_TypeDef *DCUx,
+ en_event_src_t enTriggerSrc)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO uint32_t *TRGSELx = DCU_TRGSELx(DCUx);
+
+ if (NULL != TRGSELx)
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_TRG_SRC_EVENT(enTriggerSrc));
+
+ *TRGSELx = (*TRGSELx & (~((uint32_t)EVT_MAX))) | (uint32_t)enTriggerSrc;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable DCU common trigger.
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ ** \param [in] enComTrigger DCU common trigger selection. See @ref en_dcu_com_trigger_t for details.
+ ** \param [in] enState Enable or disable the specified common trigger.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void DCU_ComTriggerCmd(M4_DCU_TypeDef *DCUx,
+ en_dcu_com_trigger_t enComTrigger,
+ en_functional_state_t enState)
+{
+ uint32_t u32ComTrig = (uint32_t)enComTrigger;
+ __IO uint32_t *TRGSELx = DCU_TRGSELx(DCUx);
+
+ if (NULL != TRGSELx)
+ {
+ DDL_ASSERT(IS_DCU_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (enState == Enable)
+ {
+ *TRGSELx |= (u32ComTrig << 30u);
+ }
+ else
+ {
+ *TRGSELx &= ~(u32ComTrig << 30u);
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get DCU trigger source register address
+ **
+ ** \param [in] DCUx Pointer to DCU instance register base
+ ** \arg M4_DCU1 DCU unit 1 instance register base
+ ** \arg M4_DCU2 DCU unit 2 instance register base
+ ** \arg M4_DCU3 DCU unit 3 instance register base
+ ** \arg M4_DCU4 DCU unit 4 instance register base
+ **
+ ** \retval DCUx_TRGSEL address DCUx is valid
+ ** \retval NULL DCUx is invalid
+ **
+ ******************************************************************************/
+static __IO uint32_t* DCU_TRGSELx(const M4_DCU_TypeDef *DCUx)
+{
+ __IO uint32_t *TRGSELx = NULL;
+
+ if (M4_DCU1 == DCUx)
+ {
+ TRGSELx = &M4_AOS->DCU1_TRGSEL;
+ }
+ else if (M4_DCU2 == DCUx)
+ {
+ TRGSELx = &M4_AOS->DCU2_TRGSEL;
+ }
+ else if (M4_DCU3 == DCUx)
+ {
+ TRGSELx = &M4_AOS->DCU3_TRGSEL;
+ }
+ else if (M4_DCU4 == DCUx)
+ {
+ TRGSELx = &M4_AOS->DCU4_TRGSEL;
+ }
+ else
+ {
+ TRGSELx = NULL;
+ }
+
+ return TRGSELx;
+}
+
+//@} // DcuGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_dmac.c b/lib/hc32f460/driver/src/hc32f460_dmac.c new file mode 100644 index 00000000..0e613491 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_dmac.c @@ -0,0 +1,2125 @@ +/******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_dmac.c
+ **
+ ** A detailed description is available at
+ ** @link DmacGroup DMAC description @endlink
+ **
+ ** - 2018-11-18 CDT First version for Device Driver Library of DMAC.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_dmac.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup DmacGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define DMA_CNT (10u)
+#define DMA_IDLE (0u)
+#define DMA_BUSY (1u)
+
+#define DMACH0 (0x01u)
+#define DMACH1 (0x02u)
+#define DMACH2 (0x04u)
+#define DMACH3 (0x08u)
+
+#define DMATIMEOUT1 (0x5000u)
+#define DMATIMEOUT2 (0x1000u)
+
+#define DMA_CHCTL_DEFAULT (0x00001000ul)
+#define DMA_DTCTL_DEFAULT (0x00000001ul)
+#define DMA_DAR_DEFAULT (0x00000000ul)
+#define DMA_SAR_DEFAULT (0x00000000ul)
+#define DMA_RPT_DEFAULT (0x00000000ul)
+#define DMA_LLP_DEFAULT (0x00000000ul)
+#define DMA_SNSEQCTL_DEFAULT (0x00000000ul)
+#define DMA_DNSEQCTL_DEFAULT (0x00000000ul)
+#define DMA_RCFGCTL_DEFAULT (0x00000000ul)
+
+/***************** Bits definition for DMA_INTSTAT0 register ****************/
+#define DMA_INTSTAT0_TRNERR_Pos (0U) /*!< DMA_INTSTAT0: TRNERR Position */
+#define DMA_INTSTAT0_REQERR_Pos (16U) /*!< DMA_INTSTAT0: REQERR Position */
+
+/***************** Bits definition for DMA_INTSTAT1 register ****************/
+#define DMA_INTSTAT1_TC_Pos (0U) /*!< DMA_INTSTAT1: TC Position */
+#define DMA_INTSTAT1_BTC_Pos (16U) /*!< DMA_INTSTAT1: BTC Position */
+
+/***************** Bits definition for DMA_INTMASK0 register ****************/
+#define DMA_INTMASK0_MSKTRNERR_Pos (0U) /*!< DMA_INTMASK0: MSKTRNERR Position */
+#define DMA_INTMASK0_MSKREQERR_Pos (16U) /*!< DMA_INTMASK0: MSKREQERR Position */
+
+/***************** Bits definition for DMA_INTMASK1 register ****************/
+#define DMA_INTMASK1_MSKTC_Pos (0U) /*!< DMA_INTMASK1: MSKTC Position */
+#define DMA_INTMASK1_MSKBTC_Pos (16U) /*!< DMA_INTMASK1: MSKBTC Position */
+
+/***************** Bits definition for DMA_INTCLR0 register *****************/
+#define DMA_INTCLR0_CLRTRNERR_Pos (0U) /*!< DMA_INTCLR0: CLRTRNERR Position */
+#define DMA_INTCLR0_CLRREQERR_Pos (16U) /*!< DMA_INTCLR0: CLRREQERR Position */
+
+/***************** Bits definition for DMA_INTCLR1 register *****************/
+#define DMA_INTCLR1_CLRTC_Pos (0U) /*!< DMA_INTCLR1: CLRTC Position */
+#define DMA_INTCLR1_CLRBTC_Pos (16U) /*!< DMA_INTCLR1: CLRBTC Position */
+
+/******************* Bits definition for DMA_CHEN register ******************/
+#define DMA_CHEN_CHEN_Pos (0U) /*!< DMA_CHEN: CHEN Position */
+
+/************** Bits definition for DMA_DTCTLx(x=0~3) register **************/
+#define DMA_DTCTL_BLKSIZE_Pos (0ul) /*!< DMA_DTCTLx: BLKSIZE Position */
+#define DMA_DTCTL_BLKSIZE_Msk (0x3FFul << DMA_DTCTL_BLKSIZE_Pos) /*!< DMA_DTCTLx: BLKSIZE Mask 0x000003FF */
+#define DMA_DTCTL_BLKSIZE (DMA_DTCTL_BLKSIZE_Msk)
+
+#define DMA_DTCTL_CNT_Pos (16ul) /*!< DMA_DTCTLx: CNT Position */
+#define DMA_DTCTL_CNT_Msk (0xFFFFul << DMA_DTCTL_CNT_Pos) /*!< DMA_DTCTLx: CNT Mask 0xFFFF0000 */
+#define DMA_DTCTL_CNT (DMA_DTCTL_CNT_Msk)
+
+/*************** Bits definition for DMA_RPTx(x=0~3) register ***************/
+#define DMA_RPT_SRPT_Pos (0ul) /*!< DMA_RPTx: SRPT Position */
+#define DMA_RPT_SRPT_Msk (0x3FFul << DMA_RPT_SRPT_Pos) /*!< DMA_RPTx: SRPT Mask 0x000003FF */
+#define DMA_RPT_SRPT (DMA_RPT_SRPT_Msk)
+
+#define DMA_RPT_DRPT_Pos (16ul) /*!< DMA_RPTx: DRPT Position */
+#define DMA_RPT_DRPT_Msk (0x3FFul << DMA_RPT_DRPT_Pos) /*!< DMA_RPTx: DRPT Mask 0x03FF0000 */
+#define DMA_RPT_DRPT (DMA_RPT_DRPT_Msk)
+
+/*************** Bits definition for DMA_RPTBx(x=0~3) register ***************/
+#define DMA_RPTB_SRPTB_Pos (0ul) /*!< DMA_RPTBx: SRPTB Position */
+#define DMA_RPTB_SRPTB_Msk (0x3FFul << DMA_RPTB_SRPTB_Pos) /*!< DMA_RPTBx: SRPTB Mask 0x000003FF */
+#define DMA_RPTB_SRPTB (DMA_RPTB_SRPTB_Msk)
+
+#define DMA_RPTB_DRPTB_Pos (16ul) /*!< DMA_RPTBx: DRPTB Position */
+#define DMA_RPTB_DRPTB_Msk (0x3FFul << DMA_RPTB_DRPTB_Pos) /*!< DMA_RPTBx: DRPTB Mask 0x03FF0000 */
+#define DMA_RPTB_DRPTB (DMA_RPTB_DRPTB_Msk)
+
+/************* Bits definition for DMA_SNSEQCTLx(x=0~3) register ************/
+#define DMA_SNSEQCTL_SOFFSET_Pos (0ul) /*!< DMA_SNSEQCTLx: SOFFSET Position */
+#define DMA_SNSEQCTL_SOFFSET_Msk (0xFFFFFul << DMA_SNSEQCTL_SOFFSET_Pos) /*!< DMA_SNSEQCTLx: SOFFSET Mask 0x000FFFFF */
+#define DMA_SNSEQCTL_SOFFSET (DMA_SNSEQCTL_SOFFSET_Msk)
+
+#define DMA_SNSEQCTL_SNSCNT_Pos (20ul) /*!< DMA_SNSEQCTLx: SNSCNT Position */
+#define DMA_SNSEQCTL_SNSCNT_Msk (0xFFFul << DMA_SNSEQCTL_SNSCNT_Pos) /*!< DMA_SNSEQCTLx: SNSCNT Mask 0xFFF00000 */
+#define DMA_SNSEQCTL_SNSCNT (DMA_SNSEQCTL_SNSCNT_Msk)
+
+/************* Bits definition for DMA_SNSEQCTLBx(x=0~3) register ************/
+#define DMA_SNSEQCTLB_SNSDIST_Pos (0ul) /*!< DMA_SNSEQCTLBx: SNSDIST Position */
+#define DMA_SNSEQCTLB_SNSDIST_Msk (0xFFFFFul << DMA_SNSEQCTLB_SNSDIST_Pos) /*!< DMA_SNSEQCTLBx: SNSDIST Mask 0x000FFFFF */
+#define DMA_SNSEQCTLB_SNSDIST (DMA_SNSEQCTLB_SNSDIST_Msk)
+
+#define DMA_SNSEQCTLB_SNSCNTB_Pos (20ul) /*!< DMA_SNSEQCTLBx: SNSCNTB Position */
+#define DMA_SNSEQCTLB_SNSCNTB_Msk (0xFFFul << DMA_SNSEQCTLB_SNSCNTB_Pos) /*!< DMA_SNSEQCTLBx: SNSCNTB Mask 0xFFF00000 */
+#define DMA_SNSEQCTLB_SNSCNTB (DMA_SNSEQCTLB_SNSCNTB_Msk)
+
+/************* Bits definition for DMA_DNSEQCTLx(x=0~3) register ************/
+#define DMA_DNSEQCTL_DOFFSET_Pos (0ul) /*!< DMA_DNSEQCTLx: DOFFSET Position */
+#define DMA_DNSEQCTL_DOFFSET_Msk (0xFFFFFul << DMA_DNSEQCTL_DOFFSET_Pos) /*!< DMA_DNSEQCTLx: DOFFSET Mask 0x000FFFFF */
+#define DMA_DNSEQCTL_DOFFSET (DMA_DNSEQCTL_DOFFSET_Msk)
+
+#define DMA_DNSEQCTL_DNSCNT_Pos (20ul) /*!< DMA_DNSEQCTLx: DNSCNT Position */
+#define DMA_DNSEQCTL_DNSCNT_Msk (0xFFFul << DMA_DNSEQCTL_DNSCNT_Pos) /*!< DMA_DNSEQCTLx: DNSCNT Mask 0xFFF00000 */
+#define DMA_DNSEQCTL_DNSCNT (DMA_DNSEQCTL_DNSCNT_Msk)
+
+/************* Bits definition for DMA_DNSEQCTLx(x=0~3) register ************/
+#define DMA_DNSEQCTLB_DNSDIST_Pos (0ul) /*!< DMA_DNSEQCTLBx: DNSDIST Position */
+#define DMA_DNSEQCTLB_DNSDIST_Msk (0xFFFFFul << DMA_DNSEQCTLB_DNSDIST_Pos) /*!< DMA_DNSEQCTLBx: DNSDIST Mask 0x000FFFFF */
+#define DMA_DNSEQCTLB_DNSDIST (DMA_DNSEQCTLB_DNSDIST_Msk)
+
+#define DMA_DNSEQCTLB_DNSCNTB_Pos (20ul) /*!< DMA_DNSEQCTLBx: DNSCNTB Position */
+#define DMA_DNSEQCTLB_DNSCNTB_Msk (0xFFFul << DMA_DNSEQCTLB_DNSCNTB_Pos) /*!< DMA_DNSEQCTLBx: DNSCNTB Mask 0xFFF00000 */
+#define DMA_DNSEQCTLB_DNSCNTB (DMA_DNSEQCTLB_DNSCNTB_Msk)
+
+/**************** Bits definition for DMA_LLPx(x=0~7) register **************/
+#define DMA_LLP_LLP_Pos (2ul) /*!< DMA_LLPx: LLP Position */
+#define DMA_LLP_LLP_Msk (0x3FFFFFFFul << DMA_LLP_LLP_Pos) /*!< DMA_LLPx: LLP Mask 0xFFFFFFC */
+#define DMA_LLP_LLP (DMA_LLP_LLP_Msk)
+
+/*************** Bits definition for DMA_CHxCTL(x=0~3) register *************/
+#define DMA_CHCTL_SINC_Pos (0ul) /*!< DMA_CHxCTL: SINC Position */
+#define DMA_CHCTL_SINC_Msk (0x3ul << DMA_CHCTL_SINC_Pos) /*!< DMA_CHxCTL: SINC Mask 0x00000003 */
+#define DMA_CHCTL_SINC (DMA_CHCTL_SINC_Msk)
+
+#define DMA_CHCTL_DINC_Pos (2ul) /*!< DMA_CHxCTL: DINC Position */
+#define DMA_CHCTL_DINC_Msk (0x3ul << DMA_CHCTL_DINC_Pos) /*!< DMA_CHxCTL: DINC Mask 0x0000000C */
+#define DMA_CHCTL_DINC (DMA_CHCTL_DINC_Msk)
+
+#define DMA_CHCTL_SRPTEN_Pos (4ul) /*!< DMA_CHxCTL: SRPTEN Position */
+#define DMA_CHCTL_SRPTEN_Msk (0x1ul << DMA_CHCTL_SRPTEN_Pos) /*!< DMA_CHxCTL: SRPTEN Mask 0x00000010 */
+#define DMA_CHCTL_SRPTEN (DMA_CHCTL_SRPTEN_Msk)
+
+#define DMA_CHCTL_DRPTEN_Pos (5ul) /*!< DMA_CHxCTL: DRPTEN Position */
+#define DMA_CHCTL_DRPTEN_Msk (0x1ul << DMA_CHCTL_DRPTEN_Pos) /*!< DMA_CHxCTL: DRPTEN Mask 0x00000020 */
+#define DMA_CHCTL_DRPTEN (DMA_CHCTL_DRPTEN_Msk)
+
+#define DMA_CHCTL_SNSEQEN_Pos (6ul) /*!< DMA_CHxCTL: SNSEQEN Position */
+#define DMA_CHCTL_SNSEQEN_Msk (0x1ul << DMA_CHCTL_SNSEQEN_Pos) /*!< DMA_CHxCTL: SNSEQEN Mask 0x00000040 */
+#define DMA_CHCTL_SNSEQEN (DMA_CHCTL_SNSEQEN_Msk)
+
+#define DMA_CHCTL_DNSEQEN_Pos (7ul) /*!< DMA_CHxCTL: DNSEQEN Position */
+#define DMA_CHCTL_DNSEQEN_Msk (0x1ul << DMA_CHCTL_DNSEQEN_Pos) /*!< DMA_CHxCTL: DNSEQEN Mask 0x00000080 */
+#define DMA_CHCTL_DNSEQEN (DMA_CHCTL_DNSEQEN_Msk)
+
+#define DMA_CHCTL_HSIZE_Pos (8ul) /*!< DMA_CHxCTL: HSIZE Position */
+#define DMA_CHCTL_HSIZE_Msk (0x3ul << DMA_CHCTL_HSIZE_Pos) /*!< DMA_CHxCTL: HSIZE Mask 0x00000300 */
+#define DMA_CHCTL_HSIZE (DMA_CHCTL_HSIZE_Msk)
+
+#define DMA_CHCTL_LLPEN_Pos (10ul) /*!< DMA_CHxCTL: LLPEN Position */
+#define DMA_CHCTL_LLPEN_Msk (0x1ul << DMA_CHCTL_LLPEN_Pos) /*!< DMA_CHxCTL: LLPEN Mask 0x00000400 */
+#define DMA_CHCTL_LLPEN (DMA_CHCTL_LLPEN_Msk)
+
+#define DMA_CHCTL_LLPRUN_Pos (11ul) /*!< DMA_CHxCTL: LLPRUN Position */
+#define DMA_CHCTL_LLPRUN_Msk (0x1ul << DMA_CHCTL_LLPRUN_Pos) /*!< DMA_CHxCTL: LLPRUN Mask 0x00000800 */
+#define DMA_CHCTL_LLPRUN (DMA_CHCTL_LLPRUN_Msk)
+
+#define DMA_CHCTL_IE_Pos (12ul) /*!< DMA_CHxCTL: IE Position */
+#define DMA_CHCTL_IE_Msk (0x1ul << DMA_CHCTL_IE_Pos) /*!< DMA_CHxCTL: IE Mask 0x00001000 */
+#define DMA_CHCTL_IE (DMA_CHCTL_IE_Msk)
+
+/*********************** DMA REGISTERx(x=0~3) register **********************/
+#define _DMA_CH_REG_OFFSET(ch) ((ch) * 0x40ul)
+#define _DMA_CH_REG(reg_base, ch) (*(volatile uint32_t *)((uint32_t)(reg_base) + _DMA_CH_REG_OFFSET(ch)))
+
+#define WRITE_DMA_CH_REG(reg_base, ch, val) (_DMA_CH_REG((reg_base), (ch)) = (val))
+#define READ_DMA_CH_REG(reg_base, ch) (_DMA_CH_REG((reg_base), (ch)))
+
+#define SET_DMA_CH_REG_BIT(reg_base, ch, pos) (_DMA_CH_REG((reg_base), (ch)) |= (1ul << (pos)))
+#define CLR_DMA_CH_REG_BIT(reg_base, ch, pos) (_DMA_CH_REG((reg_base), (ch)) &= (~(1ul << (pos))))
+
+#define WRITE_DMA_CH_TRGSEL(reg_base, ch, val) ((*(volatile uint32_t *)((uint32_t)(reg_base) + (ch) * 4ul)) = (val))
+
+#define MODIFY_DMA_CH_REG(reg_base, ch, msk, val) {do { \
+ WRITE_DMA_CH_REG((reg_base), (ch), ((READ_DMA_CH_REG((reg_base), (ch)) & (~(msk))) | ((val) << (msk##_Pos)))); \
+} while(0);}
+
+/*! Parameter valid check for Dmac register pointer. */
+#define IS_VALID_DMA_REG(x) \
+( (M4_DMA1 == (x)) || \
+ (M4_DMA2 == (x)))
+
+/*! Parameter valid check for Dmac Channel. */
+#define IS_VALID_CH(x) \
+( (DmaCh0 == (x)) || \
+ (DmaCh1 == (x)) || \
+ (DmaCh2 == (x)) || \
+ (DmaCh3 == (x)))
+
+/*! Parameter valid check for Dmac irq selection. */
+#define IS_VALID_IRQ_SEL(x) \
+( (TrnErrIrq == (x)) || \
+ (TrnReqErrIrq == (x)) || \
+ (TrnCpltIrq == (x)) || \
+ (BlkTrnCpltIrq == (x)))
+
+/*! Parameter valid check for Dmac re_config count mode. */
+#define IS_VALID_CNT_MODE(x) \
+( (CntFix == (x)) || \
+ (CntSrcAddr == (x)) || \
+ (CntDesAddr == (x)))
+
+/*! Parameter valid check for Dmac re_config source address mode. */
+#define IS_VALID_SADDR_MODE(x) \
+( (SaddrFix == (x)) || \
+ (SaddrNseq == (x)) || \
+ (SaddrRep == (x)))
+
+/*! Parameter valid check for Dmac re_config destination address mode. */
+#define IS_VALID_DADDR_MODE(x) \
+( (DaddrFix == (x)) || \
+ (DaddrNseq == (x)) || \
+ (DaddrRep == (x)))
+
+/*! Parameter valid check for Dmac status. */
+#define IS_VALID_DMA_STA(x) \
+( (DmaSta == (x)) || \
+ (ReCfgSta == (x)) || \
+ (DmaCh0Sta == (x)) || \
+ (DmaCh1Sta == (x)) || \
+ (DmaCh2Sta == (x)) || \
+ (DmaCh3Sta == (x)))
+
+/*! Parameter valid check for Dmac status. */
+#define IS_VALID_DMA_REQ_STA(x) \
+( (ReCfgReqSta == (x)) || \
+ (DmaCh0ReqSta == (x)) || \
+ (DmaCh1ReqSta == (x)) || \
+ (DmaCh2ReqSta == (x)) || \
+ (DmaCh3ReqSta == (x)))
+
+/*! Parameter valid check for Dmac transfer data width. */
+#define IS_VALID_TRN_WIDTH(x) \
+( (Dma8Bit == (x)) || \
+ (Dma16Bit == (x)) || \
+ (Dma32Bit == (x)))
+
+/*! Parameter valid check for Dmac address mode. */
+#define IS_VALID_ADDR_MODE(x) \
+( (AddressFix == (x)) || \
+ (AddressIncrease == (x)) || \
+ (AddressDecrease == (x)))
+
+/*! Parameter valid check for Dmac link-list-pointer mode. */
+#define IS_VALID_LLP_MODE(x) \
+( (LlpWaitNextReq == (x)) || \
+ (LlpRunNow == (x)))
+
+/*! Parameter validity check for DMA common trigger. */
+#define IS_DMA_COM_TRIGGER(x) \
+( ((x) == DmaComTrigger_1) || \
+ ((x) == DmaComTrigger_2) || \
+ ((x) == DmaComTrigger_1_2))
+
+/*! Parameter valid check for Dmac transfer block size. */
+#define IS_VALID_BLKSIZE(x) \
+( !((x) & (uint16_t)(~(DMA_DTCTL_BLKSIZE_Msk >> DMA_DTCTL_BLKSIZE_Pos))))
+
+/*! Parameter valid check for Dmac transfer count. */
+#define IS_VALID_TRNCNT(x) \
+( !((x) & ~(DMA_DTCTL_CNT_Msk >> DMA_DTCTL_CNT_Pos)))
+
+/*! Parameter valid check for Dmac source repeat size. */
+#define IS_VALID_SRPT_SIZE(x) \
+( !((x) & ~(DMA_RPT_SRPT_Msk >> DMA_RPT_SRPT_Pos)))
+
+/*! Parameter valid check for Dmac destination repeat size. */
+#define IS_VALID_DRPT_SIZE(x) \
+( !((x) & ~(DMA_RPT_DRPT_Msk >> DMA_RPT_DRPT_Pos)))
+
+/*! Parameter valid check for Dmac source repeatB size. */
+#define IS_VALID_SRPTB_SIZE(x) \
+( !((x) & ~(DMA_RPTB_SRPTB_Msk >> DMA_RPTB_SRPTB_Pos)))
+
+/*! Parameter valid check for Dmac destinationB repeat size. */
+#define IS_VALID_DRPTB_SIZE(x) \
+( !((x) & ~(DMA_RPTB_DRPTB_Msk >> DMA_RPTB_DRPTB_Pos)))
+
+/*! Parameter valid check for Dmac source no-sequence count. */
+#define IS_VALID_SNSCNT(x) \
+( !((x) & ~(DMA_SNSEQCTL_SNSCNT_Msk >> DMA_SNSEQCTL_SNSCNT_Pos)))
+
+/*! Parameter valid check for Dmac source no-sequence offset. */
+#define IS_VALID_SNSOFFSET(x) \
+( !((x) & ~(DMA_SNSEQCTL_SOFFSET_Msk >> DMA_SNSEQCTL_SOFFSET_Pos)))
+
+/*! Parameter valid check for Dmac source no-sequence countB. */
+#define IS_VALID_SNSCNTB(x) \
+( !((x) & ~(DMA_SNSEQCTLB_SNSCNTB_Msk >> DMA_SNSEQCTLB_SNSCNTB_Pos)))
+
+/*! Parameter valid check for Dmac source no-sequence distance. */
+#define IS_VALID_SNSDIST(x) \
+( !((x) & ~(DMA_SNSEQCTLB_SNSDIST_Msk >> DMA_SNSEQCTLB_SNSDIST_Pos)))
+
+/*! Parameter valid check for Dmac destination no-sequence count. */
+#define IS_VALID_DNSCNT(x) \
+( !((x) & ~(DMA_DNSEQCTL_DNSCNT_Msk >> DMA_DNSEQCTL_DNSCNT_Pos)))
+
+/*! Parameter valid check for Dmac destination no-sequence offset. */
+#define IS_VALID_DNSOFFSET(x) \
+( !((x) & ~(DMA_DNSEQCTL_DOFFSET_Msk >> DMA_DNSEQCTL_DOFFSET_Pos)))
+
+/*! Parameter valid check for Dmac destination no-sequence countB. */
+#define IS_VALID_DNSCNTB(x) \
+( !((x) & ~(DMA_DNSEQCTLB_DNSCNTB_Msk >> DMA_DNSEQCTLB_DNSCNTB_Pos)))
+
+/*! Parameter valid check for Dmac destination no-sequence distance. */
+#define IS_VALID_DNSDIST(x) \
+( !((x) & ~(DMA_DNSEQCTLB_DNSDIST_Msk >> DMA_DNSEQCTLB_DNSDIST_Pos)))
+
+/*! Parameter valid check for Dmac link-list-pointer. */
+#define IS_VALID_LLP(x) (!((x) & ~DMA_LLP_LLP_Msk))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+static volatile uint8_t DmaChEnState = DMA_IDLE;
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the dma.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] enNewState The new state of dma
+ ** \arg Enable Enable dma.
+ ** \arg Disable Disable dma.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void DMA_Cmd(M4_DMA_TypeDef* pstcDmaReg, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcDmaReg->EN_f.EN = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable the specified dma interrupt.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] enIrqSel The specified dma flag.
+ ** \arg TrnErrIrq The DMA transfer error interrupt.
+ ** \arg TrnReqErrIrq DMA transfer req over error interrupt.
+ ** \arg TrnCpltIrq DMA transfer completion interrupt.
+ ** \arg BlkTrnCpltIrq DMA block completion interrupt.
+ **
+ ** \retval Ok Interrupt enabled normally.
+ ** \retval ErrorInvalidParameter u8Ch or enIrqSel is invalid.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_EnableIrq(M4_DMA_TypeDef* pstcDmaReg,
+ uint8_t u8Ch,
+ en_dma_irq_sel_t enIrqSel)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_IRQ_SEL(enIrqSel));
+
+ if(!IS_VALID_CH(u8Ch))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ switch(enIrqSel)
+ {
+ case TrnErrIrq:
+ pstcDmaReg->INTMASK0 &= ~(1ul << (u8Ch + DMA_INTMASK0_MSKTRNERR_Pos));
+ break;
+ case TrnReqErrIrq:
+ pstcDmaReg->INTMASK0 &= ~(1ul << (u8Ch + DMA_INTMASK0_MSKREQERR_Pos));
+ break;
+ case TrnCpltIrq:
+ pstcDmaReg->INTMASK1 &= ~(1ul << (u8Ch + DMA_INTMASK1_MSKTC_Pos));
+ break;
+ case BlkTrnCpltIrq:
+ pstcDmaReg->INTMASK1 &= ~(1ul << (u8Ch + DMA_INTMASK1_MSKBTC_Pos));
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable the specified dma interrupt.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] enIrqSel The specified dma flag.
+ ** \arg TrnErrIrq The DMA transfer error interrupt.
+ ** \arg TrnReqErrIrq DMA transfer req over error interrupt.
+ ** \arg TrnCpltIrq DMA transfer completion interrupt.
+ ** \arg BlkTrnCpltIrq DMA block completion interrupt.
+ **
+ ** \retval Ok Interrupt disabled normally.
+ ** \retval ErrorInvalidParameter u8Ch or enIrqSel is invalid.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_DisableIrq(M4_DMA_TypeDef* pstcDmaReg,
+ uint8_t u8Ch,
+ en_dma_irq_sel_t enIrqSel)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_IRQ_SEL(enIrqSel));
+
+ if(!IS_VALID_CH(u8Ch))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ switch(enIrqSel)
+ {
+ case TrnErrIrq:
+ pstcDmaReg->INTMASK0 |= (1ul << (u8Ch + DMA_INTMASK0_MSKTRNERR_Pos));
+ break;
+ case TrnReqErrIrq:
+ pstcDmaReg->INTMASK0 |= (1ul << (u8Ch + DMA_INTMASK0_MSKREQERR_Pos));
+ break;
+ case TrnCpltIrq:
+ pstcDmaReg->INTMASK1 |= (1ul << (u8Ch + DMA_INTMASK1_MSKTC_Pos));
+ break;
+ case BlkTrnCpltIrq:
+ pstcDmaReg->INTMASK1 |= (1ul << (u8Ch + DMA_INTMASK1_MSKBTC_Pos));
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the specified dma interrupt flag status.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] enIrqSel The specified dma flag.
+ ** \arg TrnErrIrq The DMA transfer error interrupt.
+ ** \arg TrnReqErrIrq DMA transfer req over error interrupt.
+ ** \arg TrnCpltIrq DMA transfer completion interrupt.
+ ** \arg BlkTrnCpltIrq DMA block completion interrupt.
+ **
+ ** \retval the specified dma flag status
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t DMA_GetIrqFlag(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, en_dma_irq_sel_t enIrqSel)
+{
+ uint32_t u32IntStat = 0ul;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_IRQ_SEL(enIrqSel));
+
+ switch(enIrqSel)
+ {
+ case TrnErrIrq:
+ u32IntStat = (pstcDmaReg->INTSTAT0 & (1ul << (u8Ch \
+ + DMA_INTSTAT0_TRNERR_Pos)));
+ break;
+ case TrnReqErrIrq:
+ u32IntStat = (pstcDmaReg->INTSTAT0 & (1ul << (u8Ch \
+ + DMA_INTSTAT0_REQERR_Pos)));
+ break;
+ case TrnCpltIrq:
+ u32IntStat = (pstcDmaReg->INTSTAT1 & (1ul << (u8Ch \
+ + DMA_INTSTAT1_TC_Pos)));
+ break;
+ case BlkTrnCpltIrq:
+ u32IntStat = (pstcDmaReg->INTSTAT1 & (1ul << (u8Ch \
+ + DMA_INTSTAT1_BTC_Pos)));
+ break;
+ default:
+ break;
+ }
+
+ return (u32IntStat ? Set:Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the specified dma interrupt.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] enIrqSel The specified dma flag.
+ ** \arg TrnErrIrq The DMA transfer error interrupt.
+ ** \arg TrnReqErrIrq DMA transfer req over error interrupt.
+ ** \arg TrnCpltIrq DMA transfer completion interrupt.
+ ** \arg BlkTrnCpltIrq DMA block completion interrupt.
+ **
+ ** \retval Ok Clear flag successfully.
+ ** \retval ErrorInvalidParameter u8Ch or enIrqSel is invalid.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_ClearIrqFlag(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, en_dma_irq_sel_t enIrqSel)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_IRQ_SEL(enIrqSel));
+
+ if(!IS_VALID_CH(u8Ch))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ switch(enIrqSel)
+ {
+ case TrnErrIrq:
+ pstcDmaReg->INTCLR0 |= (1ul << (u8Ch + DMA_INTCLR0_CLRTRNERR_Pos));
+ break;
+ case TrnReqErrIrq:
+ pstcDmaReg->INTCLR0 |= (1ul << (u8Ch + DMA_INTCLR0_CLRREQERR_Pos));
+ break;
+ case TrnCpltIrq:
+ pstcDmaReg->INTCLR1 |= (1ul << (u8Ch + DMA_INTCLR1_CLRTC_Pos));
+ break;
+ case BlkTrnCpltIrq:
+ pstcDmaReg->INTCLR1 |= (1ul << (u8Ch + DMA_INTCLR1_CLRBTC_Pos));
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] enNewState The new state of dma
+ ** \arg Enable Enable dma.
+ ** \arg Disable Disable dma.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_ChannelCmd(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, en_functional_state_t enNewState)
+{
+ uint16_t u16Timeout = 0u;
+ uint32_t u32Temp = 0u;
+ uint32_t u32Cnt;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(DMA_IDLE == DmaChEnState)
+ {
+ DmaChEnState = DMA_BUSY;
+
+ /* Read back channel enable register except current channel */
+ u32Temp = (pstcDmaReg->CHEN & (~(1ul << u8Ch)));
+ if(0ul != u32Temp)
+ {
+ if(((pstcDmaReg->CHEN & 0x01ul) == 0x01ul) && (u8Ch != DmaCh0))
+ {
+ u32Cnt = pstcDmaReg->DTCTL0_f.CNT;
+ if(pstcDmaReg->MONDTCTL0_f.CNT > DMA_CNT)
+ {
+ /* not wait. */
+ }
+ else if(pstcDmaReg->MONDTCTL0_f.CNT < u32Cnt)
+ {
+ while(Reset != (pstcDmaReg->CHEN & 0x01ul))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT1)
+ {
+ DmaChEnState = DMA_IDLE;
+ return ErrorTimeout;
+ }
+ }
+ }
+ }
+ if(((pstcDmaReg->CHEN & 0x02ul) == 0x02ul) && (u8Ch != DmaCh1))
+ {
+ u32Cnt = pstcDmaReg->DTCTL1_f.CNT;
+ if(pstcDmaReg->MONDTCTL1_f.CNT > DMA_CNT)
+ {
+ /* not wait. */
+ }
+ else if(pstcDmaReg->MONDTCTL1_f.CNT < u32Cnt)
+ {
+ u16Timeout = 0u;
+ while(Reset != (pstcDmaReg->CHEN & 0x02ul))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT1)
+ {
+ DmaChEnState = DMA_IDLE;
+ return ErrorTimeout;
+ }
+ }
+ }
+ }
+ if(((pstcDmaReg->CHEN & 0x04ul) == 0x04ul) && (u8Ch != DmaCh2))
+ {
+ u16Timeout = 0u;
+ u32Cnt = pstcDmaReg->DTCTL2_f.CNT;
+ if(pstcDmaReg->MONDTCTL2_f.CNT > DMA_CNT)
+ {
+ /* not wait. */
+ }
+ else if(pstcDmaReg->MONDTCTL2_f.CNT < u32Cnt)
+ {
+ while(Reset != (pstcDmaReg->CHEN & 0x04ul))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT1)
+ {
+ DmaChEnState = DMA_IDLE;
+ return ErrorTimeout;
+ }
+ }
+ }
+ }
+ if(((pstcDmaReg->CHEN & 0x08ul) == 0x08ul) && (u8Ch != DmaCh3))
+ {
+ u16Timeout = 0u;
+ u32Cnt = pstcDmaReg->DTCTL3_f.CNT;
+ if(pstcDmaReg->MONDTCTL3_f.CNT > DMA_CNT)
+ {
+ /* not wait. */
+ }
+ else if(pstcDmaReg->MONDTCTL3_f.CNT < u32Cnt)
+ {
+ while(Reset != (pstcDmaReg->CHEN & 0x08ul))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT1)
+ {
+ DmaChEnState = DMA_IDLE;
+ return ErrorTimeout;
+ }
+ }
+ }
+ }
+ }
+
+ switch(enNewState)
+ {
+ case Enable:
+ pstcDmaReg->CHEN |= (1ul << (u8Ch + DMA_CHEN_CHEN_Pos)) & 0x0fu;
+ break;
+ case Disable:
+ pstcDmaReg->CHEN &= (~(1ul << (u8Ch + DMA_CHEN_CHEN_Pos))) & 0x0fu;
+ break;
+ }
+
+ DmaChEnState = DMA_IDLE;
+ return Ok;
+ }
+
+ return Error;
+}
+
+/**
+ *******************************************************************************
+ ** \brief DMA repeat & non_sequence Re_Config control configuration.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] pstcDmaReCfg The configuration struct of DMA.
+ ** \arg u16SrcRptBSize The source repeat size.
+ ** \arg u16SrcRptBSize; The source repeat size.
+ ** \arg u16DesRptBSize; The destination repeat size.
+ ** \arg enSaddrMd; DMA re_config source address mode.
+ ** \arg enDaddrMd; DMA re_config destination address mode.
+ ** \arg enCntMd; DMA re_config count mode.
+ ** \arg stcSrcNseqBCfg; The source no_sequence re_config.
+ ** \arg stcDesNseqBCfg; The destination no_sequence re_config.
+ **
+ ** \retval None
+ **
+ ** \note This function should be used while DMA disable.
+ **
+ ******************************************************************************/
+void DMA_InitReConfig(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ const stc_dma_recfg_ctl_t* pstcDmaReCfg)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_CNT_MODE(pstcDmaReCfg->enCntMd));
+ DDL_ASSERT(IS_VALID_DADDR_MODE(pstcDmaReCfg->enDaddrMd));
+ DDL_ASSERT(IS_VALID_SADDR_MODE(pstcDmaReCfg->enSaddrMd));
+
+ pstcDmaReg->RCFGCTL_f.SARMD = pstcDmaReCfg->enSaddrMd;
+ pstcDmaReg->RCFGCTL_f.DARMD = pstcDmaReCfg->enDaddrMd;
+ pstcDmaReg->RCFGCTL_f.CNTMD = pstcDmaReCfg->enCntMd;
+ pstcDmaReg->RCFGCTL_f.RCFGCHS = u8Ch;
+
+ if(SaddrRep == pstcDmaReCfg->enSaddrMd)
+ {
+ /* Set DMA source repeat size B. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch, DMA_RPT_SRPT, (uint32_t)pstcDmaReCfg->u16SrcRptBSize);
+ }
+ else if(SaddrNseq == pstcDmaReCfg->enSaddrMd)
+ {
+ /* Set DMA source no_sequence B. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTLB0, u8Ch, DMA_SNSEQCTL_SOFFSET, pstcDmaReCfg->stcSrcNseqBCfg.u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTLB0, u8Ch, DMA_SNSEQCTL_SNSCNT, (uint32_t)pstcDmaReCfg->stcSrcNseqBCfg.u16Cnt);
+ }
+ else
+ {
+ /* */
+ }
+
+ if(DaddrRep == pstcDmaReCfg->enDaddrMd)
+ {
+ /* Set DMA destination repeat size B. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch, DMA_RPT_DRPT, (uint32_t)pstcDmaReCfg->u16DesRptBSize);
+ }
+ else if(DaddrNseq == pstcDmaReCfg->enDaddrMd)
+ {
+ /* Set DMA destination no_sequence B. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTLB0, u8Ch, DMA_DNSEQCTL_DOFFSET, pstcDmaReCfg->stcDesNseqBCfg.u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTLB0, u8Ch, DMA_DNSEQCTL_DNSCNT, (uint32_t)pstcDmaReCfg->stcDesNseqBCfg.u16Cnt);
+ }
+ else
+ {
+ /* */
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Disable or enable DMA Re_Config.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] enNewState The new state of dma
+ ** \arg Enable Enable dma.
+ ** \arg Disable Disable dma.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void DMA_ReCfgCmd(M4_DMA_TypeDef* pstcDmaReg, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcDmaReg->RCFGCTL_f.RCFGEN = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configure DMA Re_Config LLP.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \param [in] enNewState The new state of dma
+ ** \arg Enable Enable dma.
+ ** \arg Disable Disable dma.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void DMA_ReCfgLlp(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcDmaReg->RCFGCTL_f.RCFGCHS = u8Ch;
+ pstcDmaReg->RCFGCTL_f.RCFGLLP = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the specified dma flag status.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] enDmaChFlag The specified dma flag.
+ ** \arg DmaSta The DMA status.
+ ** \arg ReCfgSta The DMA re_config stauts.
+ ** \arg DmaCh0Sta The DMA channel 0 status.
+ ** \arg DmaCh1Sta The DMA channel 1 status.
+ ** \arg DmaCh2Sta The DMA channel 2 status.
+ ** \arg DmaCh3Sta The DMA channel 3 status.
+ **
+ ** \retval the specified dma flag status
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t DMA_GetChFlag(M4_DMA_TypeDef* pstcDmaReg, en_dma_ch_flag_t enDmaChFlag)
+{
+ uint32_t u32IntStat = 0ul;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_DMA_STA(enDmaChFlag));
+
+ switch(enDmaChFlag)
+ {
+ case DmaSta:
+ u32IntStat = pstcDmaReg->CHSTAT_f.DMAACT;
+ break;
+ case ReCfgSta:
+ u32IntStat = pstcDmaReg->CHSTAT_f.RCFGACT;
+ break;
+ case DmaCh0Sta:
+ u32IntStat = (pstcDmaReg->CHSTAT_f.CHACT & DMACH0);
+ break;
+ case DmaCh1Sta:
+ u32IntStat = (pstcDmaReg->CHSTAT_f.CHACT & DMACH1);
+ break;
+ case DmaCh2Sta:
+ u32IntStat = (pstcDmaReg->CHSTAT_f.CHACT & DMACH2);
+ break;
+ case DmaCh3Sta:
+ u32IntStat = (pstcDmaReg->CHSTAT_f.CHACT & DMACH3);
+ break;
+ default:
+ break;
+ }
+ return (u32IntStat ? Set:Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the specified dma request status.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 register
+ ** \arg M4_DMA2 DMAC unit 2 register
+ **
+ ** \param [in] enDmaReqStatus The specified dma requst status.
+ ** \arg ReCfgReqSta The DMA re_config requst status.
+ ** \arg DmaCh0ReqSta The DMA channel 0 transfer requst status.
+ ** \arg DmaCh1ReqSta The DMA channel 1 transfer requst status.
+ ** \arg DmaCh2ReqSta The DMA channel 2 transfer requst status.
+ ** \arg DmaCh3ReqSta The DMA channel 3 transfer requst status.
+ **
+ ** \retval the specified dma requst status
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t DMA_GetReqStatus(M4_DMA_TypeDef* pstcDmaReg, en_dma_req_status_t enDmaReqStatus)
+{
+ uint32_t u32IntStat = 0ul;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_DMA_REQ_STA(enDmaReqStatus));
+
+ switch(enDmaReqStatus)
+ {
+ case ReCfgReqSta:
+ u32IntStat = pstcDmaReg->REQSTAT_f.RCFGREQ;
+ break;
+ case DmaCh0ReqSta:
+ u32IntStat = (pstcDmaReg->REQSTAT_f.CHREQ & DMACH0);
+ break;
+ case DmaCh1ReqSta:
+ u32IntStat = (pstcDmaReg->REQSTAT_f.CHREQ & DMACH1);
+ break;
+ case DmaCh2ReqSta:
+ u32IntStat = (pstcDmaReg->REQSTAT_f.CHREQ & DMACH2);
+ break;
+ case DmaCh3ReqSta:
+ u32IntStat = (pstcDmaReg->REQSTAT_f.CHREQ & DMACH3);
+ break;
+ default:
+ break;
+ }
+ return (u32IntStat ? Set:Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the source address of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2 DMAC unit 2 registers
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u32Address The source address.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetSrcAddress(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint32_t u32Address)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ WRITE_DMA_CH_REG(&pstcDmaReg->SAR0, u8Ch, u32Address);
+
+ /* Ensure the address has been writed */
+ while(u32Address != READ_DMA_CH_REG(&pstcDmaReg->MONSAR0, u8Ch))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ WRITE_DMA_CH_REG(&pstcDmaReg->SAR0, u8Ch, u32Address);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get current source address of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2 DMAC unit 2 registers
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The current source address.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetSrcAddr(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ return READ_DMA_CH_REG(&pstcDmaReg->MONSAR0, u8Ch);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the destination address of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2 DMAC unit 2 registers
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u32Address The destination address.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetDesAddress(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint32_t u32Address)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ WRITE_DMA_CH_REG(&pstcDmaReg->DAR0, u8Ch, u32Address);
+
+ /* Ensure the address has been writed */
+ while(u32Address != READ_DMA_CH_REG(&pstcDmaReg->MONDAR0, u8Ch))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ WRITE_DMA_CH_REG(&pstcDmaReg->DAR0, u8Ch, u32Address);
+ }
+ }
+
+ return enRet;
+
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get current destination address of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2 DMAC unit 2 registers
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The current destination address.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetDesAddr(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ return READ_DMA_CH_REG(&pstcDmaReg->MONDAR0, u8Ch);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the block size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u16BlkSize The block size.
+ **
+ ** \retval None.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetBlockSize(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint16_t u16BlkSize)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_BLKSIZE(u16BlkSize));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DTCTL0, u8Ch, DMA_DTCTL_BLKSIZE, (uint32_t)u16BlkSize);
+
+ /* Ensure the block size has been writed */
+ while(u16BlkSize != (uint16_t)(READ_DMA_CH_REG(&pstcDmaReg->MONDTCTL0, u8Ch) & DMA_DTCTL_BLKSIZE))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DTCTL0, u8Ch, DMA_DTCTL_BLKSIZE, (uint32_t)u16BlkSize);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the block size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The current block size.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetBlockSize(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ return (READ_DMA_CH_REG(&pstcDmaReg->MONDTCTL0, u8Ch) & DMA_DTCTL_BLKSIZE);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the transfer count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u16TrnCnt The transfer count.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetTransferCnt(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint16_t u16TrnCnt)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_TRNCNT(u16TrnCnt));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DTCTL0, u8Ch, DMA_DTCTL_CNT, (uint32_t)u16TrnCnt);
+
+ /* Ensure the transfer count has been writed */
+ while(u16TrnCnt != ((READ_DMA_CH_REG(&pstcDmaReg->MONDTCTL0, u8Ch) & DMA_DTCTL_CNT) >> DMA_DTCTL_CNT_Pos))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DTCTL0, u8Ch, DMA_DTCTL_CNT, (uint32_t)u16TrnCnt);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the remain transfer count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The remain transfer count.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetTransferCnt(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ uint32_t u32Count;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ u32Count = READ_DMA_CH_REG(&pstcDmaReg->MONDTCTL0, u8Ch) & DMA_DTCTL_CNT;
+
+ return (u32Count >> DMA_DTCTL_CNT_Pos);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the source repeat size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u16Size The source repeat size.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetSrcRptSize(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint16_t u16Size)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_SRPT_SIZE(u16Size));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPT0, u8Ch, DMA_RPT_SRPT, (uint32_t)u16Size);
+
+ /* Ensure the source repeat size has been writed */
+ while(u16Size != (uint16_t)(READ_DMA_CH_REG(&pstcDmaReg->MONRPT0, u8Ch) & DMA_RPT_SRPT))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPT0, u8Ch, DMA_RPT_SRPT, (uint32_t)u16Size);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the source repeat size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The source repeat size.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetSrcRptSize(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ return (READ_DMA_CH_REG(&pstcDmaReg->MONRPT0, u8Ch) & DMA_RPT_SRPT);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the destination repeat size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u16Size The destination repeat size.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetDesRptSize(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint16_t u16Size)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_DRPT_SIZE(u16Size));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPT0, u8Ch, DMA_RPT_DRPT, (uint32_t)u16Size);
+
+ /* Ensure the destination repeat size has been writed */
+ while(u16Size != ((READ_DMA_CH_REG(&pstcDmaReg->MONRPT0, u8Ch) & DMA_RPT_DRPT) >> DMA_RPT_DRPT_Pos))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPT0, u8Ch, DMA_RPT_DRPT, (uint32_t)u16Size);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the destination repeat size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The destination repeat size.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetDesRptSize(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ uint32_t u32Size;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ u32Size = READ_DMA_CH_REG(&pstcDmaReg->MONRPT0, u8Ch) & DMA_RPT_DRPT;
+
+ return (u32Size >> DMA_RPT_DRPT_Pos);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the source repeat size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u16Size The source repeat size.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetSrcRptbSize(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint16_t u16Size)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_SRPTB_SIZE(u16Size));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch, DMA_RPTB_SRPTB, (uint32_t)u16Size);
+
+ /* Ensure the source repeat size has been writed */
+ while(u16Size != (uint16_t)(READ_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch) & DMA_RPTB_SRPTB))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch, DMA_RPTB_SRPTB, (uint32_t)u16Size);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the destination repeat size of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u16Size The destination repeat size.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetDesRptBSize(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint16_t u16Size)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_DRPTB_SIZE(u16Size));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch, DMA_RPTB_DRPTB, (uint32_t)u16Size);
+
+ /* Ensure the destination repeat size has been writed */
+ while(u16Size != ((READ_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch) & DMA_RPTB_DRPTB) >> DMA_RPTB_DRPTB_Pos))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPTB0, u8Ch, DMA_RPTB_DRPTB, (uint32_t)u16Size);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the source no-sequence offset & count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] pstcSrcNseqCfg
+ ** \arg u32offset The source no-sequence offset.
+ ** \arg u16cnt The source no-sequence count.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetSrcNseqCfg(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ const stc_dma_nseq_cfg_t* pstcSrcNseqCfg)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_SNSOFFSET(pstcSrcNseqCfg->u32Offset));
+ DDL_ASSERT(IS_VALID_SNSCNT(pstcSrcNseqCfg->u16Cnt));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch,
+ DMA_SNSEQCTL_SOFFSET, pstcSrcNseqCfg->u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch,
+ DMA_SNSEQCTL_SNSCNT, (uint32_t)pstcSrcNseqCfg->u16Cnt);
+
+ /* Ensure the no-sequence offset & count has been writed */
+ while((pstcSrcNseqCfg->u32Offset | ((uint32_t)pstcSrcNseqCfg->u16Cnt << DMA_SNSEQCTL_SNSCNT_Pos))
+ != READ_DMA_CH_REG(&pstcDmaReg->MONSNSEQCTL0, u8Ch))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch,
+ DMA_SNSEQCTL_SOFFSET, pstcSrcNseqCfg->u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch,
+ DMA_SNSEQCTL_SNSCNT, (uint32_t)pstcSrcNseqCfg->u16Cnt);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the source no-sequence offset & count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] pstcSrcNseqBCfg
+ ** \arg u32NseqDist The source no-sequence distance.
+ ** \arg u16cntB The source no-sequence count.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetSrcNseqBCfg(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ const stc_dma_nseqb_cfg_t* pstcSrcNseqBCfg)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_SNSDIST(pstcSrcNseqBCfg->u32NseqDist));
+ DDL_ASSERT(IS_VALID_SNSCNTB(pstcSrcNseqBCfg->u16CntB));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTLB0, u8Ch, DMA_SNSEQCTLB_SNSDIST, pstcSrcNseqBCfg->u32NseqDist);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTLB0, u8Ch, DMA_SNSEQCTLB_SNSCNTB, (uint32_t)pstcSrcNseqBCfg->u16CntB);
+
+ /* Ensure the no-sequence offset & count has been writed */
+ while((pstcSrcNseqBCfg->u32NseqDist | ((uint32_t)pstcSrcNseqBCfg->u16CntB << DMA_SNSEQCTLB_SNSCNTB_Pos))
+ != READ_DMA_CH_REG(&pstcDmaReg->SNSEQCTLB0, u8Ch))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTLB0, u8Ch,
+ DMA_SNSEQCTLB_SNSDIST, pstcSrcNseqBCfg->u32NseqDist);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTLB0, u8Ch,
+ DMA_SNSEQCTLB_SNSCNTB, (uint32_t)pstcSrcNseqBCfg->u16CntB);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the destination no-sequence offset & count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] pstcDesNseqCfg
+ ** \arg u32offset The destination no-sequence offset.
+ ** \arg u16cnt The destination no-sequence count.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetDesNseqCfg(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ const stc_dma_nseq_cfg_t* pstcDesNseqCfg)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_DNSOFFSET(pstcDesNseqCfg->u32Offset));
+ DDL_ASSERT(IS_VALID_DNSCNT(pstcDesNseqCfg->u16Cnt));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch, DMA_DNSEQCTL_DOFFSET, pstcDesNseqCfg->u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch, DMA_DNSEQCTL_DNSCNT, (uint32_t)pstcDesNseqCfg->u16Cnt);
+
+ /* Ensure the no-sequence offset & count has been writed */
+ while((pstcDesNseqCfg->u32Offset | ((uint32_t)pstcDesNseqCfg->u16Cnt << DMA_DNSEQCTL_DNSCNT_Pos))
+ != READ_DMA_CH_REG(&pstcDmaReg->MONDNSEQCTL0, u8Ch))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch,
+ DMA_DNSEQCTL_DOFFSET, pstcDesNseqCfg->u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch,
+ DMA_DNSEQCTL_DNSCNT, (uint32_t)pstcDesNseqCfg->u16Cnt);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the destination no-sequence offset & count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] pstcDesNseqBCfg
+ ** \arg u32offset The destination no-sequence offset.
+ ** \arg u16cnt The destination no-sequence count.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetDesNseqBCfg(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ const stc_dma_nseqb_cfg_t* pstcDesNseqBCfg)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_DNSDIST(pstcDesNseqBCfg->u32NseqDist));
+ DDL_ASSERT(IS_VALID_DNSCNTB(pstcDesNseqBCfg->u16CntB));
+
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTLB0, u8Ch, DMA_DNSEQCTLB_DNSDIST, pstcDesNseqBCfg->u32NseqDist);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTLB0, u8Ch, DMA_DNSEQCTLB_DNSCNTB, (uint32_t)pstcDesNseqBCfg->u16CntB);
+
+ /* Ensure the no-sequence offset & count has been writed */
+ while((pstcDesNseqBCfg->u32NseqDist | ((uint32_t)pstcDesNseqBCfg->u16CntB << DMA_DNSEQCTLB_DNSCNTB_Pos))
+ != READ_DMA_CH_REG(&pstcDmaReg->DNSEQCTLB0, u8Ch))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTLB0, u8Ch,
+ DMA_DNSEQCTLB_DNSDIST, pstcDesNseqBCfg->u32NseqDist);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTLB0, u8Ch,
+ DMA_DNSEQCTLB_DNSCNTB, (uint32_t)pstcDesNseqBCfg->u16CntB);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the source no-sequence count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The source no-sequence count.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetSrcNSeqCount(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ uint32_t u32Count;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ u32Count = READ_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch) & DMA_SNSEQCTL_SNSCNT;
+
+ return (u32Count >> DMA_SNSEQCTL_SNSCNT_Pos);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the destination no-sequence count of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The destination no-sequence count.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetDesNSeqCount(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ uint32_t u32Count;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ u32Count = READ_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch) & DMA_DNSEQCTL_DNSCNT;
+
+ return (u32Count >> DMA_DNSEQCTL_DNSCNT_Pos);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the source no-sequence offset of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The source no-sequence offset.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetSrcNSeqOffset(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ return (READ_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch) & DMA_SNSEQCTL_SOFFSET);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the destination no-sequence offset of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ **
+ ** \retval uint32_t The destination no-sequence offset.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+uint32_t DMA_GetDesNSeqOffset(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ return (READ_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch) & DMA_DNSEQCTL_DOFFSET);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set linked list pointer of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] u32Pointer The decriptor pointer.
+ **
+ ** \retval None.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t DMA_SetLLP(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, uint32_t u32Pointer)
+{
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_LLP(u32Pointer));
+
+ WRITE_DMA_CH_REG(&pstcDmaReg->LLP0, u8Ch, u32Pointer);
+
+ /* Ensure the destination repeat size has been writed */
+ while(u32Pointer != ((READ_DMA_CH_REG(&pstcDmaReg->LLP0, u8Ch) & DMA_LLP_LLP) >> DMA_LLP_LLP_Pos))
+ {
+ u16Timeout++;
+ if(u16Timeout > DMATIMEOUT2)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ WRITE_DMA_CH_REG(&pstcDmaReg->LLP0, u8Ch, u32Pointer);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set The DMA trigger source.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] enSrc The DMA trigger source.
+ **
+ ** \retval None.
+ **
+ ** \note Before call this function, shoud ensure enable AOS.
+ **
+ ******************************************************************************/
+void DMA_SetTriggerSrc(const M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, en_event_src_t enSrc)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+
+ if(M4_DMA1 == pstcDmaReg)
+ {
+ WRITE_DMA_CH_TRGSEL(&M4_AOS->DMA1_TRGSEL0,u8Ch,enSrc);
+ }
+ else if(M4_DMA2 == pstcDmaReg)
+ {
+ WRITE_DMA_CH_TRGSEL(&M4_AOS->DMA2_TRGSEL0,u8Ch,enSrc);
+ }
+ else
+ {
+ //else
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable DMA common trigger..
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] enComTrigger DMA common trigger selection.
+ ** \arg DmaComTrigger_1
+ ** \arg DmaComTrigger_2
+ ** \arg DmaComTrigger_1_2
+ ** \param [in] enNewState Enable or disable the specified common trigger.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void DMA_ComTriggerCmd(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ en_dma_com_trigger_t enComTrigger, en_functional_state_t enNewState)
+{
+ __IO uint32_t *TRGSELx;
+ uint32_t u32ComTrig = (uint32_t)enComTrigger;
+
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_DMA_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if (M4_DMA1 == pstcDmaReg)
+ {
+ TRGSELx = (uint32_t *)((uint32_t)(&M4_AOS->DMA1_TRGSEL0) + u8Ch*4UL);
+ }
+ else
+ {
+ TRGSELx = (uint32_t *)((uint32_t)(&M4_AOS->DMA2_TRGSEL0) + u8Ch*4UL);
+ }
+
+ if (Enable == enNewState)
+ {
+ *TRGSELx |= (u32ComTrig << 30u);
+ }
+ else
+ {
+ *TRGSELx &= ~(u32ComTrig << 30u);
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable DMA re-config common trigger..
+ **
+ ** \param [in] enComTrigger DMA common trigger selection.
+ ** \arg DmaComTrigger_1
+ ** \arg DmaComTrigger_2
+ ** \arg DmaComTrigger_1_2
+ ** \param [in] enNewState Enable or disable the specified common trigger.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void DMA_ReConfigComTriggerCmd(en_dma_com_trigger_t enComTrigger, en_functional_state_t enNewState)
+{
+ uint32_t u32ComTrig = (uint32_t)enComTrigger;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+ DDL_ASSERT(IS_DMA_COM_TRIGGER(enComTrigger));
+
+ if (Enable == enNewState)
+ {
+ M4_AOS->DMA_TRGSELRC |= (u32ComTrig << 30u);
+ }
+ else
+ {
+ M4_AOS->DMA_TRGSELRC &= ~(u32ComTrig << 30u);
+ }
+}
+/**
+ *******************************************************************************
+ ** \brief Set linked list pointer of the specified dma channel.
+ **
+ ** \param [in] enSrc The DMA trigger source.
+ **
+ ** \retval None.
+ **
+ ** \note Before call this function, should ensure enable AOS.
+ **
+ ******************************************************************************/
+void DMA_SetReConfigTriggerSrc(en_event_src_t enSrc)
+{
+
+ M4_AOS->DMA_TRGSELRC_f.TRGSEL = enSrc;
+
+}
+/**
+ *******************************************************************************
+ ** \brief The configuration of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] pstcChCfg The configuration pointer.
+ ** \arg enSrcInc The source address mode.
+ ** \arg enDesInc The destination address mode.
+ ** \arg enSrcRptEn The source repeat function(enable or disable).
+ ** \arg enDesRptEn The destination repeat function(enable or disable).
+ ** \arg enSrcNseqEn The source no_sequence function(enable or disable).
+ ** \arg enDesNseqEn The destination no_sequence function(enable or disable).
+ ** \arg enTrnWidth The transfer data width.
+ ** \arg enLlpEn The linked list pointer function(enable or disable).
+ ** \arg enLlpMd The linked list pointer mode.
+ ** \arg enIntEn The interrupt function(enable or disable).
+ **
+ ** \retval None.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void DMA_ChannelCfg(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ const stc_dma_ch_cfg_t* pstcChCfg)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_ADDR_MODE(pstcChCfg->enSrcInc));
+ DDL_ASSERT(IS_VALID_ADDR_MODE(pstcChCfg->enDesInc));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcChCfg->enSrcRptEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcChCfg->enDesRptEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcChCfg->enSrcNseqEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcChCfg->enDesNseqEn));
+ DDL_ASSERT(IS_VALID_TRN_WIDTH(pstcChCfg->enTrnWidth));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcChCfg->enLlpEn));
+ DDL_ASSERT(IS_VALID_LLP_MODE(pstcChCfg->enLlpMd));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcChCfg->enIntEn));
+
+ /* Set the source address mode. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_SINC, pstcChCfg->enSrcInc);
+ /* Set the destination address mode. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_DINC, pstcChCfg->enDesInc);
+ /* Enable or disable source repeat function. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_SRPTEN, pstcChCfg->enSrcRptEn);
+ /* Enable or disable destination repeat function. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_DRPTEN, pstcChCfg->enDesRptEn);
+ /* Enable or disable source no_sequence function. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_SNSEQEN, pstcChCfg->enSrcNseqEn);
+ /* Enable or disable destination no_sequence function. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_DNSEQEN, pstcChCfg->enDesNseqEn);
+ /* Set the transfer data width. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_HSIZE, pstcChCfg->enTrnWidth);
+ /* Enable or disable linked list pointer no_sequence function. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_LLPEN, pstcChCfg->enLlpEn);
+ /* Set the linked list pointer mode. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_LLPRUN, pstcChCfg->enLlpMd);
+ /* Enable or disable channel interrupt function. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_IE, pstcChCfg->enIntEn);
+}
+
+/**
+ *******************************************************************************
+ ** \brief The configuration of the specified dma channel.
+ **
+ ** \param [in] pstcDmaReg The pointer to dma register
+ ** \arg M4_DMA1 DMAC unit 1 registers
+ ** \arg M4_DMA2
+ **
+ ** \param [in] u8Ch The specified dma channel.
+ ** \param [in] pstcDmaCfg The configuration pointer.
+ ** \arg enSrcInc The source address mode.
+ ** \arg enDesInc The destination address mode.
+ ** \arg enSrcRptEn The source repeat function(enable or disable).
+ ** \arg enDesRptEn The destination repeat function(enable or disable).
+ ** \arg enSrcNseqEn The source no_sequence function(enable or disable).
+ ** \arg enDesNseqEn The destination no_sequence function(enable or disable).
+ ** \arg enTrnWidth The transfer data width.
+ ** \arg enLlpEn The linked list pointer function(enable or disable).
+ ** \arg enLlpMd The linked list pointer mode.
+ ** \arg enIntEn The interrupt function(enable or disable).
+ **
+ ** \retval None.
+ **
+ ** \note This function should be used after enable DMAx clk(PWC_Fcg0PeriphClockCmd)
+ ** and before channel enable.
+ **
+ ******************************************************************************/
+void DMA_InitChannel(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch,
+ const stc_dma_config_t* pstcDmaCfg)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+ DDL_ASSERT(IS_VALID_BLKSIZE(pstcDmaCfg->u16BlockSize));
+ DDL_ASSERT(IS_VALID_TRNCNT(pstcDmaCfg->u16TransferCnt));
+ DDL_ASSERT(IS_VALID_SRPT_SIZE(pstcDmaCfg->u16SrcRptSize));
+ DDL_ASSERT(IS_VALID_DRPT_SIZE(pstcDmaCfg->u16DesRptSize));
+
+ /* Enable DMA. */
+ DMA_Cmd(pstcDmaReg, Enable);
+ /* Disable DMA interrupt */
+ CLR_DMA_CH_REG_BIT(&pstcDmaReg->CHCTL0 , u8Ch, DMA_CHCTL_IE_Pos);
+ /* Set DMA source address. */
+ WRITE_DMA_CH_REG(&pstcDmaReg->SAR0, u8Ch, pstcDmaCfg->u32SrcAddr);
+ /* Set DMA destination address. */
+ WRITE_DMA_CH_REG(&pstcDmaReg->DAR0, u8Ch, pstcDmaCfg->u32DesAddr);
+ /* Set DMA transfer block size. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DTCTL0, u8Ch, DMA_DTCTL_BLKSIZE, (uint32_t)pstcDmaCfg->u16BlockSize);
+ /* Set DMA transfer count. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DTCTL0, u8Ch, DMA_DTCTL_CNT, (uint32_t)pstcDmaCfg->u16TransferCnt);
+ /* Set DMA source repeat size. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPT0, u8Ch, DMA_RPT_SRPT, (uint32_t)pstcDmaCfg->u16SrcRptSize);
+ /* Set DMA destination repeat size. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->RPT0, u8Ch, DMA_RPT_DRPT, (uint32_t)pstcDmaCfg->u16DesRptSize);
+ /* Set DMA source no_sequence. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch, DMA_SNSEQCTL_SOFFSET, pstcDmaCfg->stcSrcNseqCfg.u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch, DMA_SNSEQCTL_SNSCNT, (uint32_t)pstcDmaCfg->stcSrcNseqCfg.u16Cnt);
+ /* Set DMA destination no_sequence. */
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch, DMA_DNSEQCTL_DOFFSET, pstcDmaCfg->stcDesNseqCfg.u32Offset);
+ MODIFY_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch, DMA_DNSEQCTL_DNSCNT, (uint32_t)pstcDmaCfg->stcDesNseqCfg.u16Cnt);
+ /* Set DMA linked list pointer. */
+ WRITE_DMA_CH_REG(&pstcDmaReg->LLP0, u8Ch, pstcDmaCfg->u32DmaLlp);
+ /* Set DMA channel parameter. */
+ DMA_ChannelCfg(pstcDmaReg, u8Ch, &pstcDmaCfg->stcDmaChCfg);
+}
+
+void DMA_DeInit(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch)
+{
+ DDL_ASSERT(IS_VALID_DMA_REG(pstcDmaReg));
+ DDL_ASSERT(IS_VALID_CH(u8Ch));
+
+ /* reset dma channel */
+ WRITE_DMA_CH_REG(&pstcDmaReg->CHCTL0, u8Ch, DMA_CHCTL_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->DTCTL0, u8Ch, DMA_DTCTL_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->DAR0, u8Ch, DMA_DAR_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->SAR0, u8Ch, DMA_SAR_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->SNSEQCTL0, u8Ch, DMA_SNSEQCTL_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->DNSEQCTL0, u8Ch, DMA_DNSEQCTL_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->RPT0, u8Ch, DMA_RPT_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->LLP0, u8Ch, DMA_LLP_DEFAULT);
+ WRITE_DMA_CH_REG(&pstcDmaReg->RCFGCTL, u8Ch, DMA_RCFGCTL_DEFAULT);
+
+ /* Set trigger source event max */
+ DMA_SetTriggerSrc(pstcDmaReg, u8Ch, EVT_MAX);
+ /* disable channel */
+ DMA_ChannelCmd(pstcDmaReg, u8Ch, Disable);
+}
+
+//@} // DmacGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_efm.c b/lib/hc32f460/driver/src/hc32f460_efm.c new file mode 100644 index 00000000..d8583efe --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_efm.c @@ -0,0 +1,938 @@ +/******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_efm.c
+ **
+ ** A detailed description is available at
+ ** @link EfmGroup EFM description @endlink
+ **
+ ** - 2018-10-29 CDT First version for Device Driver Library of EFM.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_efm.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup EfmGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define EFM_LOCK (0x00000000u)
+#define EFM_UNLOCK (0x00000001u)
+#define EFM_KEY1 (0x0123ul)
+#define EFM_KEY2 (0x3210ul)
+
+#define EFM_PROTECT_ADDR_MSK (0x000FFFFFu)
+
+/* Parameter validity check for pointer. */
+#define IS_VALID_POINTER(x) (NULL != (x))
+
+/* Parameter validity check for flash latency. */
+#define IS_VALID_FLASH_LATENCY(x) \
+( ((x) == EFM_LATENCY_0) || \
+ ((x) == EFM_LATENCY_1) || \
+ ((x) == EFM_LATENCY_2) || \
+ ((x) == EFM_LATENCY_3) || \
+ ((x) == EFM_LATENCY_4) || \
+ ((x) == EFM_LATENCY_5) || \
+ ((x) == EFM_LATENCY_6) || \
+ ((x) == EFM_LATENCY_7) || \
+ ((x) == EFM_LATENCY_8) || \
+ ((x) == EFM_LATENCY_9) || \
+ ((x) == EFM_LATENCY_10) || \
+ ((x) == EFM_LATENCY_11) || \
+ ((x) == EFM_LATENCY_12) || \
+ ((x) == EFM_LATENCY_13) || \
+ ((x) == EFM_LATENCY_14) || \
+ ((x) == EFM_LATENCY_15))
+
+/* Parameter validity check for read mode. */
+#define IS_VALID_READ_MD(MD) \
+( ((MD) == NormalRead) || \
+ ((MD) == UltraPowerRead))
+
+/* Parameter validity check for erase/program mode. */
+#define IS_VALID_ERASE_PGM_MD(MD) \
+( ((MD) == EFM_MODE_READONLY) || \
+ ((MD) == EFM_MODE_SINGLEPROGRAM) || \
+ ((MD) == EFM_MODE_SINGLEPROGRAMRB) || \
+ ((MD) == EFM_MODE_SEQUENCEPROGRAM) || \
+ ((MD) == EFM_MODE_SECTORERASE) || \
+ ((MD) == EFM_MODE_CHIPERASE))
+
+/* Parameter validity check for flash flag. */
+#define IS_VALID_FLASH_FLAG(flag) \
+( ((flag) == EFM_FLAG_WRPERR) || \
+ ((flag) == EFM_FLAG_PEPRTERR) || \
+ ((flag) == EFM_FLAG_PGSZERR) || \
+ ((flag) == EFM_FLAG_PGMISMTCH) || \
+ ((flag) == EFM_FLAG_EOP) || \
+ ((flag) == EFM_FLAG_COLERR) || \
+ ((flag) == EFM_FLAG_RDY))
+
+/* Parameter validity check for flash clear flag. */
+#define IS_VALID_CLEAR_FLASH_FLAG(flag) \
+( ((flag) == EFM_FLAG_WRPERR) || \
+ ((flag) == EFM_FLAG_PEPRTERR) || \
+ ((flag) == EFM_FLAG_PGSZERR) || \
+ ((flag) == EFM_FLAG_PGMISMTCH) || \
+ ((flag) == EFM_FLAG_EOP) || \
+ ((flag) == EFM_FLAG_COLERR))
+
+/* Parameter validity check for flash interrupt. */
+#define IS_VALID_EFM_INT_SEL(int) \
+( ((int) == PgmErsErrInt) || \
+ ((int) == EndPgmInt) || \
+ ((int) == ColErrInt))
+
+/* Parameter validity check for flash address. */
+#define IS_VALID_FLASH_ADDR(addr) \
+( ((addr) == 0x00000000u) || \
+ (((addr) >= 0x00000001u) && \
+ ((addr) <= 0x0007FFDFu)))
+
+/* Parameter validity check for flash address. */
+#define IS_VALID_OTP_LOCK_ADDR(addr) \
+( ((addr) >= 0x03000FC0u) || \
+ ((addr) <= 0x03000FF8u))
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Unlock the flash.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_Unlock(void)
+{
+ M4_EFM->FAPRT = EFM_KEY1;
+ M4_EFM->FAPRT = EFM_KEY2;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Lock the flash.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_Lock(void)
+{
+ if(EFM_UNLOCK == M4_EFM->FAPRT)
+ {
+ M4_EFM->FAPRT = EFM_KEY2;
+ M4_EFM->FAPRT = EFM_KEY2;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the flash.
+ **
+ ** \param [in] enNewState The new state of the flash.
+ ** \arg Enable Enable flash.
+ ** \arg Disable Stop flash.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_FlashCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ M4_EFM->FSTP_f.FSTP = ((Enable == enNewState) ? 0ul : 1ul);
+}
+/**
+ *******************************************************************************
+ ** \brief Sets the code latency value..
+ **
+ ** \param [in] u32Latency specifies the FLASH Latency value.
+ ** \arg EFM_LATENCY_0 FLASH 0 Latency cycle
+ ** \arg EFM_LATENCY_1 FLASH 1 Latency cycle
+ ** \arg EFM_LATENCY_2 FLASH 2 Latency cycles
+ ** \arg EFM_LATENCY_3 FLASH 3 Latency cycles
+ ** \arg EFM_LATENCY_4 FLASH 4 Latency cycles
+ ** \arg EFM_LATENCY_5 FLASH 5 Latency cycles
+ ** \arg EFM_LATENCY_6 FLASH 6 Latency cycles
+ ** \arg EFM_LATENCY_7 FLASH 7 Latency cycles
+ ** \arg EFM_LATENCY_8 FLASH 8 Latency cycles
+ ** \arg EFM_LATENCY_9 FLASH 9 Latency cycles
+ ** \arg EFM_LATENCY_10 FLASH 10 Latency cycles
+ ** \arg EFM_LATENCY_11 FLASH 11 Latency cycles
+ ** \arg EFM_LATENCY_12 FLASH 12 Latency cycles
+ ** \arg EFM_LATENCY_13 FLASH 13 Latency cycles
+ ** \arg EFM_LATENCY_14 FLASH 14 Latency cycles
+ ** \arg EFM_LATENCY_15 FLASH 15 Latency cycles
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_SetLatency(uint32_t u32Latency)
+{
+ DDL_ASSERT(IS_VALID_FLASH_LATENCY(u32Latency));
+
+ M4_EFM->FRMC_f.FLWT = u32Latency;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the flash instruction cache.
+ **
+ ** \param [in] enNewState The new state of the flash instruction cache.
+ ** \arg Enable Enable flash instruction cache.
+ ** \arg Disable Disable flash instruction cache.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_InstructionCacheCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ M4_EFM->FRMC_f.CACHE = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the data cache reset.
+ **
+ ** \param [in] enNewState The new state of the data cache reset.
+ ** \arg Enable Enable data cache reset.
+ ** \arg Disable Disable data cache reset.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_DataCacheRstCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ M4_EFM->FRMC_f.CRST = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the flash read mode.
+ **
+ ** \param [in] enReadMD The flash read mode.
+ ** \arg NormalRead Normal read mode.
+ ** \arg UltraPowerRead Ultra_Low power read mode.
+ **
+ ** \retval None.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_SetReadMode(en_efm_read_md_t enReadMD)
+{
+ DDL_ASSERT(IS_VALID_READ_MD(enReadMD));
+ M4_EFM->FRMC_f.SLPMD = enReadMD;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable erase / program.
+ **
+ ** \param [in] enNewState The new state of the erase / program.
+ ** \arg Enable Enable erase / program.
+ ** \arg Disable Disable erase / program.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_ErasePgmCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ M4_EFM->FWMC_f.PEMODE = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the flash erase program mode.
+ **
+ ** \param [in] u32Mode The flash erase program mode.
+ ** \arg EFM_MODE_READONLY The flash read only.
+ ** \arg EFM_MODE_SINGLEPROGRAM The flash single program.
+ ** \arg EFM_MODE_SINGLEPROGRAMRB The flash single program with read back.
+ ** \arg EFM_MODE_SEQUENCEPROGRAM The flash sequence program.
+ ** \arg EFM_MODE_SECTORERASE The flash sector erase.
+ ** \arg EFM_MODE_CHIPERASE The flash mass erase.
+ **
+ ** \retval en_result_t.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t EFM_SetErasePgmMode(uint32_t u32Mode)
+{
+ en_result_t enRet = Ok;
+ uint16_t u16Timeout = 0u;
+
+ DDL_ASSERT(IS_VALID_ERASE_PGM_MD(u32Mode));
+
+ while(1ul != M4_EFM->FSR_f.RDY)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ if(Ok == enRet)
+ {
+ M4_EFM->FWMC_f.PEMODE = Enable;
+ M4_EFM->FWMC_f.PEMOD = u32Mode;
+ M4_EFM->FWMC_f.PEMODE = Disable;
+ }
+
+ return enRet;
+}
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the specified interrupt.
+ **
+ ** \param [in] enInt The specified interrupt.
+ ** \arg PgmErsErrInt Program erase error interrupt.
+ ** \arg EndPgmInt End of Program interrupt.
+ ** \arg ReadErrInt Read collided error flag.
+ **
+ ** \param [in] enNewState The new state of the specified interrupt.
+ ** \arg Enable Enable the specified interrupt.
+ ** \arg Disable Disable the specified interrupt.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_InterruptCmd(en_efm_int_sel_t enInt, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+ DDL_ASSERT(IS_VALID_EFM_INT_SEL(enInt));
+
+ switch(enInt)
+ {
+ case PgmErsErrInt:
+ M4_EFM->FITE_f.PEERRITE = enNewState;
+ break;
+ case EndPgmInt:
+ M4_EFM->FITE_f.OPTENDITE = enNewState;
+ break;
+ case ColErrInt:
+ M4_EFM->FITE_f.COLERRITE = enNewState;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Checks whether the specified FLASH flag is set or not..
+ **
+ ** \param [in] u32flag Specifies the FLASH flag to check.
+ ** \arg EFM_FLAG_WRPERR Flash write protect error flag.
+ ** \arg EFM_FLAG_PEPRTERR Flash program protect area error flag.
+ ** \arg EFM_FLAG_PGSZERR Flash program size error flag.
+ ** \arg EFM_FLAG_PGMISMTCH Flash program miss match flag.
+ ** \arg EFM_FLAG_EOP Flash end of program flag.
+ ** \arg EFM_FLAG_COLERR Flash collision error flag.
+ ** \arg EFM_FLAG_RDY Flash ready flag.
+ **
+ ** \retval The flash status.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t EFM_GetFlagStatus(uint32_t u32flag)
+{
+ DDL_ASSERT(IS_VALID_FLASH_FLAG(u32flag));
+
+ return ((0ul == (M4_EFM->FSR & u32flag)) ? Reset :Set);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Checks whether the specified FLASH flag is set or not..
+ **
+ ** \param [in] u32flag Specifies the FLASH flag to clear.
+ ** \arg EFM_FLAG_WRPERR Flash write protect error flag.
+ ** \arg EFM_FLAG_PEPRTERR Flash program protect area error flag.
+ ** \arg EFM_FLAG_PGSZERR Flash program size error flag.
+ ** \arg EFM_FLAG_PGMISMTCH Flash program miss match flag.
+ ** \arg EFM_FLAG_EOP Flash end of program flag.
+ ** \arg EFM_FLAG_COLERR Flash collision error flag.
+ **
+ ** \retval The flash status.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_ClearFlag(uint32_t u32flag)
+{
+ //DDL_ASSERT(IS_VALID_CLEAR_FLASH_FLAG(u32flag));
+
+ M4_EFM->FSCLR = u32flag;
+}
+/**
+ *******************************************************************************
+ ** \brief Get the flash status.
+ **
+ ** \param None
+ **
+ ** \retval The flash status.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_efm_flash_status_t EFM_GetStatus(void)
+{
+ en_efm_flash_status_t enFlashStatus = FlashEOP;
+
+ if(1ul == M4_EFM->FSR_f.RDY )
+ {
+ enFlashStatus = FlashReady;
+ }
+ else if(1ul == M4_EFM->FSR_f.COLERR)
+ {
+ enFlashStatus = FlashRWErr;
+ }
+ else if(1ul == M4_EFM->FSR_f.OPTEND)
+ {
+ enFlashStatus = FlashEOP;
+ }
+ else if(1ul == M4_EFM->FSR_f.PGMISMTCH)
+ {
+ enFlashStatus = FlashPgMissMatch;
+ }
+ else if(1ul == M4_EFM->FSR_f.PGSZERR)
+ {
+ enFlashStatus = FlashPgSizeErr;
+ }
+ else if(1ul == M4_EFM->FSR_f.PEPRTERR)
+ {
+ enFlashStatus = FlashPgareaPErr;
+ }
+ else if(1ul == M4_EFM->FSR_f.PEWERR)
+ {
+ enFlashStatus = FlashWRPErr;
+ }
+ else
+ {
+ //else
+ }
+
+ return enFlashStatus;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set flash the windows protect address.
+ **
+ ** \param [in] stcAddr The specified windows protect address.
+ ** \arg StartAddr The start of windows protect address.
+ ** \arg EndAddr The end of windows protect address.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_SetWinProtectAddr(stc_efm_win_protect_addr_t stcAddr)
+{
+ M4_EFM->FPMTSW_f.FPMTSW = (stcAddr.StartAddr & EFM_PROTECT_ADDR_MSK);
+ M4_EFM->FPMTEW_f.FPMTEW = (stcAddr.EndAddr & EFM_PROTECT_ADDR_MSK);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set bus state while flash program & erase.
+ **
+ ** \param [in] enState The specified bus state while flash program & erase.
+ ** \arg BusBusy The bus busy.
+ ** \arg BusRelease The bus release.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void EFM_SetBusState(en_efm_bus_sta_t enState)
+{
+ M4_EFM->FWMC_f.BUSHLDCTL = enState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Flash single program without read back.
+ **
+ ** \param [in] u32Addr The specified program address.
+ ** \param [in] u32Data The specified program data.
+ **
+ ** \retval en_result_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t EFM_SingleProgram(uint32_t u32Addr, uint32_t u32Data)
+{
+ en_result_t enRet = Ok;
+ uint8_t u8tmp;
+ uint16_t u16Timeout = 0u;
+
+ DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
+
+ /* CLear the error flag. */
+ EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
+ EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
+
+ /* read back CACHE */
+ u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
+
+ M4_EFM->FRMC_f.CACHE = Disable;
+
+ /* Enable program. */
+ EFM_ErasePgmCmd(Enable);
+ /* Set single program mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_SINGLEPROGRAM;
+ /* program data. */
+ *(uint32_t*)u32Addr = u32Data;
+
+ while(1ul != M4_EFM->FSR_f.RDY)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ if(u32Data != *(uint32_t*)u32Addr)
+ {
+ enRet = Error;
+ }
+
+ EFM_ClearFlag(EFM_FLAG_EOP);
+ /* Set read only mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
+ EFM_ErasePgmCmd(Disable);
+
+ /* recover CACHE */
+ M4_EFM->FRMC_f.CACHE = u8tmp;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Flash single program with read back.
+ **
+ ** \param [in] u32Addr The specified program address.
+ ** \param [in] u32Data The specified program data.
+ **
+ ** \retval en_result_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t EFM_SingleProgramRB(uint32_t u32Addr, uint32_t u32Data)
+{
+ en_result_t enRet = Ok;
+ uint8_t u8tmp = 0u;
+ uint16_t u16Timeout = 0u;
+
+ DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
+
+ /* CLear the error flag. */
+ EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
+ EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
+
+ /* read back CACHE */
+ u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
+
+ M4_EFM->FRMC_f.CACHE = Disable;
+
+ /* Enable program. */
+ EFM_ErasePgmCmd(Enable);
+ /* Set single program with read back mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_SINGLEPROGRAMRB;
+ /* program data. */
+ *(uint32_t*)u32Addr = u32Data;
+
+ while(1ul != M4_EFM->FSR_f.RDY)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ if(1ul == M4_EFM->FSR_f.PGMISMTCH)
+ {
+ enRet = Error;
+ }
+
+ EFM_ClearFlag(EFM_FLAG_EOP);
+ /* Set read only mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
+ EFM_ErasePgmCmd(Disable);
+
+ /* recover CACHE */
+ M4_EFM->FRMC_f.CACHE = u8tmp;
+
+ return enRet;
+}
+
+static void *EFM_Memcpy(void *pvDst, void *pvSrc, uint32_t u32Count)
+{
+ uint8_t *u8TmpDst = (uint8_t *)pvDst;
+ uint8_t *u8TmpSrc = (uint8_t *)pvSrc;
+
+ DDL_ASSERT(IS_VALID_POINTER(pvDst));
+ DDL_ASSERT(IS_VALID_POINTER(pvSrc));
+
+ while (u32Count--)
+ {
+ *u8TmpDst++ = *u8TmpSrc++;
+ }
+
+ return pvDst;
+}
+/**
+ *******************************************************************************
+ ** \brief Flash sequence program.
+ **
+ ** \param [in] u32Addr The specified program address.
+ ** \param [in] u32Len The len of specified program data.
+ ** \param [in] *pBuf The pointer of specified program data.
+ **
+ ** \retval en_result_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t EFM_SequenceProgram(uint32_t u32Addr, uint32_t u32Len, void *pBuf)
+{
+ en_result_t enRet = Ok;
+ uint8_t u8tmp;
+ uint32_t i;
+ uint16_t u16Timeout = 0u;
+ uint32_t u32Tmp = 0xFFFFFFFFul;
+ uint32_t *u32pSrc = pBuf;
+ uint32_t *u32pDest = (uint32_t *)u32Addr;
+ uint32_t u32LoopWords = u32Len >> 2ul;
+ uint32_t u32RemainBytes = u32Len % 4ul;
+
+ DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
+ DDL_ASSERT(IS_VALID_POINTER(pBuf));
+
+ /* CLear the error flag. */
+ EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
+ EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
+
+ /* read back CACHE */
+ u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
+
+ M4_EFM->FRMC_f.CACHE = Disable;
+
+ /* Enable program. */
+ EFM_ErasePgmCmd(Enable);
+ /* Set sequence program mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_SEQUENCEPROGRAM;
+ /* clear read collided error flag.*/
+ EFM_ClearFlag(EFM_FLAG_COLERR);
+ EFM_ClearFlag(EFM_FLAG_WRPERR);
+
+ /* program data. */
+ for(i = 0ul; i < u32LoopWords; i++)
+ {
+ *u32pDest++ = *u32pSrc++;
+ /* wait operate end. */
+ while(1ul != M4_EFM->FSR_f.OPTEND)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+ /* clear end flag. */
+ EFM_ClearFlag(EFM_FLAG_EOP);
+ }
+ if(u32RemainBytes)
+ {
+ EFM_Memcpy(&u32Tmp, u32pSrc, u32RemainBytes);
+ *u32pDest++ = u32Tmp;
+ }
+
+ /* Set read only mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
+
+ u16Timeout = 0u;
+ while(1ul != M4_EFM->FSR_f.RDY)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ EFM_ClearFlag(EFM_FLAG_EOP);
+ EFM_ErasePgmCmd(Disable);
+
+ /* recover CACHE */
+ M4_EFM->FRMC_f.CACHE = u8tmp;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Flash sector erase.
+ **
+ ** \param [in] u32Addr The uncertain(random) address in the specified sector.
+ **
+ ** \retval en_result_t
+ **
+ ** \note The address should be word align.
+ **
+ ******************************************************************************/
+en_result_t EFM_SectorErase(uint32_t u32Addr)
+{
+ uint8_t u8tmp;
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
+
+ /* CLear the error flag. */
+ EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
+ EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
+
+ /* read back CACHE */
+ u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
+
+ M4_EFM->FRMC_f.CACHE = Disable;
+
+ /* Enable erase. */
+ EFM_ErasePgmCmd(Enable);
+ /* Set sector erase mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_SECTORERASE;
+
+ *(uint32_t*)u32Addr = 0x12345678u;
+
+ while(1ul != M4_EFM->FSR_f.RDY)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ EFM_ClearFlag(EFM_FLAG_EOP);
+ /* Set read only mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
+ EFM_ErasePgmCmd(Disable);
+
+ /* recover CACHE */
+ M4_EFM->FRMC_f.CACHE = u8tmp;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Flash mass erase.
+ **
+ ** \param [in] u32Addr The uncertain(random) address in the flash.
+ **
+ ** \retval en_result_t
+ **
+ ** \note The address should be word align.
+ **
+ ******************************************************************************/
+en_result_t EFM_MassErase(uint32_t u32Addr)
+{
+ uint8_t u8tmp;
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
+
+ /* CLear the error flag. */
+ EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
+ EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
+
+ /* read back CACHE */
+ u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
+
+ M4_EFM->FRMC_f.CACHE = Disable;
+
+ /* Enable erase. */
+ EFM_ErasePgmCmd(Enable);
+ /* Set sector erase mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_CHIPERASE;
+
+ *(uint32_t*)u32Addr = 0x12345678u;
+
+ while(1ul != M4_EFM->FSR_f.RDY)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ EFM_ClearFlag(EFM_FLAG_EOP);
+ /* Set read only mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
+ EFM_ErasePgmCmd(Disable);
+
+ /* recover CACHE */
+ M4_EFM->FRMC_f.CACHE = u8tmp;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get flash switch status.
+ **
+ ** \param None.
+ **
+ ** \retval en_flag_status_t
+ ** \arg Set The flash has switched, the start address is sector1.
+ ** \arg Reset The flash did not switch, the start address is sector0.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t EFM_GetSwitchStatus(void)
+{
+ return ((0u == M4_EFM->FSWP_f.FSWP) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Lock OTP data block.
+ **
+ ** \param u32Addr The addr to lock.
+ **
+ ** \retval en_result_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t EFM_OtpLock(uint32_t u32Addr)
+{
+ DDL_ASSERT(IS_VALID_OTP_LOCK_ADDR(u32Addr));
+ uint16_t u16Timeout = 0u;
+ en_result_t enRet = Ok;
+
+ /* Enable program. */
+ EFM_ErasePgmCmd(Enable);
+ /* Set single program mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_SINGLEPROGRAM;
+
+ /* Lock the otp block. */
+ *(uint32_t*)u32Addr = 0ul;
+
+ while(1ul != M4_EFM->FSR_f.RDY)
+ {
+ u16Timeout++;
+ if(u16Timeout > 0x1000u)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ EFM_ClearFlag(EFM_FLAG_EOP);
+ /* Set read only mode. */
+ M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
+ EFM_ErasePgmCmd(Disable);
+
+ return enRet;
+}
+/**
+ *******************************************************************************
+ ** \brief read unique ID.
+ **
+ ** \param None
+ **
+ ** \retval uint32_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+stc_efm_unique_id_t EFM_ReadUID(void)
+{
+ stc_efm_unique_id_t stcUID;
+
+ stcUID.uniqueID1 = M4_EFM->UQID1;
+ stcUID.uniqueID2 = M4_EFM->UQID2;
+ stcUID.uniqueID3 = M4_EFM->UQID3;
+
+ return stcUID;
+}
+
+//@} // EfmGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_emb.c b/lib/hc32f460/driver/src/hc32f460_emb.c new file mode 100644 index 00000000..5e50088e --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_emb.c @@ -0,0 +1,483 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_emb.c
+ **
+ ** A detailed description is available at
+ ** @link EMBGroup EMB description @endlink
+ **
+ ** - 2018-11-24 CDT First version for Device Driver Library of EMB.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_emb.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup EMBGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for emb unit */
+#define IS_VALID_EMB_UNIT(__EMBx__) \
+( (M4_EMB1 == (__EMBx__)) || \
+ (M4_EMB2 == (__EMBx__)) || \
+ (M4_EMB3 == (__EMBx__)) || \
+ (M4_EMB4 == (__EMBx__)))
+
+/*!< Parameter valid check for emb status*/
+#define IS_VALID_EMB_STATUS_TYPE(x) \
+( (EMBFlagPortIn == (x)) || \
+ (EMBFlagPWMSame == (x)) || \
+ (EMBFlagCmp == (x)) || \
+ (EMBFlagOSCFail == (x)) || \
+ (EMBPortInState == (x)) || \
+ (EMBPWMState == (x)))
+
+/*!< Parameter valid check for emb status clear*/
+#define IS_VALID_EMB_STATUS_CLR(x) \
+( (EMBPortInFlagClr == (x)) || \
+ (EMBPWMSameFlagCLr == (x)) || \
+ (EMBCmpFlagClr == (x)) || \
+ (EMBOSCFailFlagCLr == (x)))
+
+/*!< Parameter valid check for emb irq enable*/
+#define IS_VALID_EMB_IRQ(x) \
+( (PORTBrkIrq == (x)) || \
+ (PWMSmBrkIrq == (x)) || \
+ (CMPBrkIrq == (x)) || \
+ (OSCFailBrkIrq == (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')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * \brief EMB interrupt request enable or disable
+ *
+ * \param [in] EMBx EMB unit
+ * \param [in] enEMBIrq Irq type
+ * \param [in] bEn true/false
+ *
+ * \retval en_result_t Ok: config success
+ ******************************************************************************/
+en_result_t EMB_ConfigIrq(M4_EMB_TypeDef *EMBx,
+ en_emb_irq_type_t enEMBIrq,
+ bool bEn)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (IS_VALID_EMB_UNIT(EMBx))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EMB_IRQ(enEMBIrq));
+
+ enRet = Ok;
+ switch (enEMBIrq)
+ {
+ case PORTBrkIrq:
+ EMBx->INTEN_f.PORTINTEN = (uint32_t)bEn;
+ break;
+ case PWMSmBrkIrq:
+ EMBx->INTEN_f.PWMINTEN = (uint32_t)bEn;
+ break;
+ case CMPBrkIrq:
+ EMBx->INTEN_f.CMPINTEN = (uint32_t)bEn;
+ break;
+ case OSCFailBrkIrq:
+ EMBx->INTEN_f.OSINTEN = (uint32_t)bEn;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get EMB status
+ **
+ ** \param [in] EMBx EMB unit
+ **
+ ** \param [in] enStatus EMB status type
+ **
+ ** \retval EMB status
+ **
+ ******************************************************************************/
+bool EMB_GetStatus(M4_EMB_TypeDef *EMBx, en_emb_status_t enStatus)
+{
+ bool status = false;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EMB_UNIT(EMBx));
+ DDL_ASSERT(IS_VALID_EMB_STATUS_TYPE(enStatus));
+
+ switch (enStatus)
+ {
+ case EMBFlagPortIn:
+ status = EMBx->STAT_f.PORTINF;
+ break;
+ case EMBFlagPWMSame:
+ status = EMBx->STAT_f.PWMSF;
+ break;
+ case EMBFlagCmp:
+ status = EMBx->STAT_f.CMPF;
+ break;
+ case EMBFlagOSCFail:
+ status = EMBx->STAT_f.OSF;
+ break;
+ case EMBPortInState:
+ status = EMBx->STAT_f.PORTINST;
+ break;
+ case EMBPWMState:
+ status = EMBx->STAT_f.PWMST;
+ break;
+ default:
+ break;
+ }
+
+ return status;
+}
+
+/**
+ *******************************************************************************
+ ** \brief EMB clear status(Recover from protection state)
+ **
+ ** \param [in] EMBx EMB unit
+ **
+ ** \param [in] enStatusClr EMB status clear type
+ **
+ ** \retval en_result_t Ok: Config Success
+ **
+ ******************************************************************************/
+en_result_t EMB_ClrStatus(M4_EMB_TypeDef *EMBx,
+ en_emb_status_clr_t enStatusClr)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (IS_VALID_EMB_UNIT(EMBx))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EMB_STATUS_CLR(enStatusClr));
+
+ enRet = Ok;
+ switch (enStatusClr)
+ {
+ case EMBPortInFlagClr:
+ EMBx->STATCLR_f.PORTINFCLR = 1ul;
+ break;
+ case EMBPWMSameFlagCLr:
+ EMBx->STATCLR_f.PWMSFCLR = 1ul;
+ break;
+ case EMBCmpFlagClr:
+ EMBx->STATCLR_f.CMPFCLR = 1ul;
+ break;
+ case EMBOSCFailFlagCLr:
+ EMBx->STATCLR_f.OSFCLR = 1ul;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief EMB Control Register(CR) for timer6
+ *
+ * \param [in] EMBx EMB unit
+ * \param [in] pstcEMBConfigCR EMB Config CR pointer
+ *
+ * \retval en_result_t Ok: Set successfully
+ * \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
+ ******************************************************************************/
+en_result_t EMB_Config_CR_Timer6(const stc_emb_ctrl_timer6_t* pstcEMBConfigCR)
+{
+ uint32_t u32Val = 0ul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != pstcEMBConfigCR)
+ {
+ if (pstcEMBConfigCR->bEnPortBrake)
+ {
+ u32Val |= 1ul;
+ }
+ if (pstcEMBConfigCR->bEnCmp1Brake)
+ {
+ u32Val |= 1ul << 1;
+ }
+ if (pstcEMBConfigCR->bEnCmp2Brake)
+ {
+ u32Val |= 1ul << 2;
+ }
+ if (pstcEMBConfigCR->bEnCmp3Brake)
+ {
+ u32Val |= 1ul << 3;
+ }
+ if (pstcEMBConfigCR->bEnOSCFailBrake)
+ {
+ u32Val |= 1ul << 5;
+ }
+ if (pstcEMBConfigCR->bEnTimer61PWMSBrake)
+ {
+ u32Val |= 1ul << 6;
+ }
+ if (pstcEMBConfigCR->bEnTimer62PWMSBrake)
+ {
+ u32Val |= 1ul << 7;
+ }
+ if (pstcEMBConfigCR->bEnTimer63PWMSBrake)
+ {
+ u32Val |= 1ul << 8;
+ }
+ if (EMBPortFltDiv0 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ }
+ if (EMBPortFltDiv8 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ u32Val |= 1ul << 28;
+ }
+ if (EMBPortFltDiv32 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ u32Val |= 2ul << 28;
+ }
+ if (EMBPortFltDiv128 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ u32Val |= 3ul << 28;
+ }
+ if (pstcEMBConfigCR->bEnPorInFlt)
+ {
+ u32Val |= 1ul << 30;
+ }
+ if (pstcEMBConfigCR->bEnPortInLevelSel_Low)
+ {
+ u32Val |= 1ul << 31;
+ }
+
+ M4_EMB1->CTL = u32Val;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+
+/*******************************************************************************
+ * \brief EMB Control Register(CR) for timer4
+ *
+ * \param [in] EMBx EMB unit
+ * \param [in] pstcEMBConfigCR EMB Config CR pointer
+ *
+ * \retval en_result_t Ok: Set successfully
+ * \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
+ ******************************************************************************/
+en_result_t EMB_Config_CR_Timer4(M4_EMB_TypeDef *EMBx,
+ const stc_emb_ctrl_timer4_t* pstcEMBConfigCR)
+{
+ uint32_t u32Val = 0ul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((M4_EMB1 != EMBx) && \
+ (IS_VALID_EMB_UNIT(EMBx)) && \
+ (NULL != pstcEMBConfigCR))
+ {
+ if (pstcEMBConfigCR->bEnPortBrake)
+ {
+ u32Val |= 1ul;
+ }
+ if (pstcEMBConfigCR->bEnCmp1Brake)
+ {
+ u32Val |= 1ul << 1;
+ }
+ if (pstcEMBConfigCR->bEnCmp2Brake)
+ {
+ u32Val |= 1ul << 2;
+ }
+ if (pstcEMBConfigCR->bEnCmp3Brake)
+ {
+ u32Val |= 1ul << 3;
+ }
+ if (pstcEMBConfigCR->bEnOSCFailBrake)
+ {
+ u32Val |= 1ul << 5;
+ }
+ if (pstcEMBConfigCR->bEnTimer4xWHLSammeBrake)
+ {
+ u32Val |= 1ul << 6;
+ }
+ if (pstcEMBConfigCR->bEnTimer4xVHLSammeBrake)
+ {
+ u32Val |= 1ul << 7;
+ }
+ if (pstcEMBConfigCR->bEnTimer4xUHLSammeBrake)
+ {
+ u32Val |= 1ul << 8;
+ }
+ if (EMBPortFltDiv0 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ }
+ if (EMBPortFltDiv8 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ u32Val |= 1ul << 28;
+ }
+ if (EMBPortFltDiv32 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ u32Val |= 2ul << 28;
+ }
+ if (EMBPortFltDiv128 == pstcEMBConfigCR->enPortInFltClkSel)
+ {
+ u32Val |= 3ul << 28;
+ }
+ if (pstcEMBConfigCR->bEnPorInFlt)
+ {
+ u32Val |= 1ul << 30;
+ }
+ if (pstcEMBConfigCR->bEnPortInLevelSel_Low)
+ {
+ u32Val |= 1ul << 31;
+ }
+
+ EMBx->CTL = u32Val;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief EMB detect PWM atcive level (short detection) selection for timer6
+ *
+ * \param [in] EMBx EMB unit
+ * \param [in] pstcEMBPWMlv EMB en detect active level pointer
+ *
+ * \retval en_result_t Ok: Set successfully
+ * \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
+ ******************************************************************************/
+en_result_t EMB_PWMLv_Timer6(const stc_emb_pwm_level_timer6_t* pstcEMBPWMlv)
+{
+ uint32_t u32Val = 0ul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != pstcEMBPWMlv)
+ {
+ if (pstcEMBPWMlv->bEnTimer61HighLevelDect)
+ {
+ u32Val |= 0x1ul;
+ }
+ if (pstcEMBPWMlv->bEnTimer62HighLevelDect)
+ {
+ u32Val |= 0x2ul;
+ }
+ if (pstcEMBPWMlv->bEnTimer63HighLevelDect)
+ {
+ u32Val |= 0x4ul;
+ }
+
+ M4_EMB1->PWMLV = u32Val;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+
+/*******************************************************************************
+ * \brief EMB detect PWM atcive level (short detection) selection for timer4
+ *
+ * \param [in] EMBx EMB unit
+ * \param [in] pstcEMBPWMlv EMB en detect active level pointer
+ *
+ * \retval en_result_t Ok: Set successfully
+ * \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
+ ******************************************************************************/
+en_result_t EMB_PWMLv_Timer4(M4_EMB_TypeDef *EMBx,
+ const stc_emb_pwm_level_timer4_t* pstcEMBPWMlv)
+{
+ uint32_t u32Val = 0ul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((IS_VALID_EMB_UNIT(EMBx)) && \
+ (M4_EMB1 != EMBx) && \
+ (NULL != pstcEMBPWMlv))
+ {
+ if (pstcEMBPWMlv->bEnWHLphaseHighLevelDect)
+ {
+ u32Val |= 0x1ul;
+ }
+ if (pstcEMBPWMlv->bEnVHLPhaseHighLevelDect)
+ {
+ u32Val |= 0x2ul;
+ }
+ if (pstcEMBPWMlv->bEnUHLPhaseHighLevelDect)
+ {
+ u32Val |= 0x4ul;
+ }
+
+ EMBx->PWMLV = u32Val;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief EMB Software brake
+ **
+ ** \param [in] EMBx EMB unit
+ **
+** \param [in] bEn true: Software Brake Enable / false: Software Brake Disable
+ **
+ ** \retval en_result_t Ok: Config Success
+ **
+ ******************************************************************************/
+en_result_t EMB_SwBrake(M4_EMB_TypeDef *EMBx, bool bEn)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EMB_UNIT(EMBx));
+
+ EMBx->SOE_f.SOE = (uint32_t)bEn;
+
+ return Ok;
+}
+
+//@} // EMBGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_event_port.c b/lib/hc32f460/driver/src/hc32f460_event_port.c new file mode 100644 index 00000000..4141d630 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_event_port.c @@ -0,0 +1,464 @@ +/******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_event_port.c
+ **
+ ** A detailed description is available at
+ ** @link EventPortGroup EventPort description @endlink
+ **
+ ** - 2018-12-07 CDT First version for Device Driver Library of EventPort.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_event_port.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup EventPortGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define EP1_BASE 0x40010800ul + 0x0100ul
+#define EP2_BASE 0x40010800ul + 0x011Cul
+#define EP3_BASE 0x40010800ul + 0x0138ul
+#define EP4_BASE 0x40010800ul + 0x0154ul
+#define EP1_DIR_BASE 0x00ul
+#define EP1_IDR_BASE 0x04ul
+#define EP1_ODR_BASE 0x08ul
+#define EP1_ORR_BASE 0x0Cul
+#define EP1_OSR_BASE 0x10ul
+#define EP1_RISR_BASE 0x14ul
+#define EP1_FAL_BASE 0x18ul
+#define EP_NFCR_BASE 0x40010800ul + 0x0170ul
+
+
+/*! Parameter validity check for port group. */
+#define IS_VALID_EVENT_PORT(x) \
+( ((x) == EventPort1) || \
+ ((x) == EventPort2) || \
+ ((x) == EventPort3) || \
+ ((x) == EventPort4))
+
+/*! Parameter validity check for pin. */
+#define IS_VALID_EVENT_PIN(x) \
+( ((x) == EventPin00) || \
+ ((x) == EventPin01) || \
+ ((x) == EventPin02) || \
+ ((x) == EventPin03) || \
+ ((x) == EventPin04) || \
+ ((x) == EventPin05) || \
+ ((x) == EventPin06) || \
+ ((x) == EventPin07) || \
+ ((x) == EventPin08) || \
+ ((x) == EventPin09) || \
+ ((x) == EventPin10) || \
+ ((x) == EventPin11) || \
+ ((x) == EventPin12) || \
+ ((x) == EventPin13) || \
+ ((x) == EventPin14) || \
+ ((x) == EventPin15))
+
+/*! Parameter valid check for Event Port common trigger. */
+#define IS_EP_COM_TRIGGER(x) \
+( ((x) == EpComTrigger_1) || \
+ ((x) == EpComTrigger_2) || \
+ ((x) == EpComTrigger_1_2))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Event Port init
+ **
+ ** \param [in] enEventPort Event port index, This parameter can be
+ ** any value of @ref en_event_port_t
+ ** \param [in] u16EventPin Event pin index, This parameter can be
+ ** any composed value of @ref en_event_pin_t
+ ** \param [in] pstcEventPortInit Structure pointer of event port configuration
+ **
+ ** \retval Ok Init successful
+ ** ErrorInvalidParameter Event port index invalid
+ **
+ ******************************************************************************/
+en_result_t EVENTPORT_Init(en_event_port_t enEventPort, uint16_t u16EventPin, \
+ const stc_event_port_init_t *pstcEventPortInit)
+{
+ en_result_t enRet = Ok;
+
+ uint32_t *EPDIRx; ///< Direction register
+ uint32_t *EPORRx; ///< Reset after trigger enable register
+ uint32_t *EPOSRx; ///< Set after trigger enable register
+ uint32_t *EPRISRx; ///< Rising edge detect enable register
+ uint32_t *EPFALx; ///< Falling edge detect enable register
+
+ EPDIRx = (uint32_t *)(EP1_BASE + EP1_DIR_BASE + (0x1C * enEventPort));
+ EPORRx = (uint32_t *)(EP1_BASE + EP1_ORR_BASE + (0x1C * enEventPort));
+ EPOSRx = (uint32_t *)(EP1_BASE + EP1_OSR_BASE + (0x1C * enEventPort));
+ EPRISRx= (uint32_t *)(EP1_BASE + EP1_RISR_BASE+ (0x1C * enEventPort));
+ EPFALx = (uint32_t *)(EP1_BASE + EP1_FAL_BASE + (0x1C * enEventPort));
+
+ /* Direction configure */
+ if (EventPortOut == pstcEventPortInit->enDirection)
+ {
+ *EPDIRx |= u16EventPin;
+ }
+ else
+ {
+ *EPDIRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ }
+
+ /* Reset if be triggered */
+ if (Enable == pstcEventPortInit->enReset)
+ {
+ *EPORRx |= u16EventPin;
+ }
+ else
+ {
+ *EPORRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ }
+
+ /* Set if be triggered */
+ if (Enable == pstcEventPortInit->enSet)
+ {
+ *EPOSRx |= u16EventPin;
+ }
+ else
+ {
+ *EPOSRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ }
+
+ /* Rising edge detect setting */
+ if (Enable == pstcEventPortInit->enRisingDetect)
+ {
+ *EPRISRx |= u16EventPin;
+ }
+ else
+ {
+ *EPRISRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ }
+
+ /* Falling edge detect setting */
+ if (Enable == pstcEventPortInit->enFallingDetect)
+ {
+ *EPFALx |= u16EventPin;
+ }
+ else
+ {
+ *EPFALx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ }
+
+ /* Noise filter setting */
+ switch (enEventPort)
+ {
+ case EventPort1:
+ M4_AOS->PEVNTNFCR_f.NFEN1 = pstcEventPortInit->enFilter;
+ M4_AOS->PEVNTNFCR_f.DIVS1 = pstcEventPortInit->enFilterClk;
+ break;
+ case EventPort2:
+ M4_AOS->PEVNTNFCR_f.NFEN2 = pstcEventPortInit->enFilter;
+ M4_AOS->PEVNTNFCR_f.DIVS2 = pstcEventPortInit->enFilterClk;
+ break;
+ case EventPort3:
+ M4_AOS->PEVNTNFCR_f.NFEN3 = pstcEventPortInit->enFilter;
+ M4_AOS->PEVNTNFCR_f.DIVS3 = pstcEventPortInit->enFilterClk;
+ break;
+ case EventPort4:
+ M4_AOS->PEVNTNFCR_f.NFEN4 = pstcEventPortInit->enFilter;
+ M4_AOS->PEVNTNFCR_f.DIVS4 = pstcEventPortInit->enFilterClk;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Event Port de-init, restore all registers to default value
+ **
+ ** \param None
+ **
+ ** \retval Ok De-init successful
+ **
+ ******************************************************************************/
+en_result_t EVENTPORT_DeInit(void)
+{
+ uint32_t EPDIRx ;
+ uint32_t EPODRx ;
+ uint32_t EPORRx ;
+ uint32_t EPOSRx ;
+ uint32_t EPRISRx;
+ uint32_t EPFALx ;
+ uint8_t u8EPCnt;
+
+ EPDIRx = (uint32_t)(EP1_BASE + EP1_DIR_BASE);
+ EPODRx = (uint32_t)(EP1_BASE + EP1_ODR_BASE);
+ EPORRx = (uint32_t)(EP1_BASE + EP1_ORR_BASE);
+ EPOSRx = (uint32_t)(EP1_BASE + EP1_OSR_BASE);
+ EPRISRx = (uint32_t)(EP1_BASE + EP1_RISR_BASE);
+ EPFALx = (uint32_t)(EP1_BASE + EP1_FAL_BASE);
+
+ /* Restore all registers to default value */
+ M4_AOS->PEVNTTRGSR12 = 0x1FFul;
+ M4_AOS->PEVNTTRGSR34 = 0x1FFul;
+ M4_AOS->PEVNTNFCR = 0ul;
+ for (u8EPCnt = 0u; u8EPCnt < 4u; u8EPCnt++)
+ {
+ *(uint32_t *)(EPDIRx + 0x1Cul * u8EPCnt) = 0ul;
+ *(uint32_t *)(EPODRx + 0x1Cul * u8EPCnt) = 0ul;
+ *(uint32_t *)(EPORRx + 0x1Cul * u8EPCnt) = 0ul;
+ *(uint32_t *)(EPOSRx + 0x1Cul * u8EPCnt) = 0ul;
+ *(uint32_t *)(EPRISRx + 0x1Cul * u8EPCnt) = 0ul;
+ *(uint32_t *)(EPFALx + 0x1Cul * u8EPCnt) = 0ul;
+ }
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Event Port trigger source select
+ **
+ ** \param [in] enEventPort Event port index, This parameter can be
+ ** any value of @ref en_event_port_t
+ ** \param [in] enTriggerSrc Event port trigger source. This parameter
+ ** can be any value of @ref en_event_src_t
+ ** \retval Ok Trigger source is set
+ ** ErrorInvalidParameter Invalid event port enum
+ **
+ ******************************************************************************/
+en_result_t EVENTPORT_SetTriggerSrc(en_event_port_t enEventPort, \
+ en_event_src_t enTriggerSrc)
+{
+ en_result_t enRet = Ok;
+ DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
+
+ if ((EventPort1 == enEventPort) || (EventPort2 == enEventPort))
+ {
+ M4_AOS->PEVNTTRGSR12 = enTriggerSrc;
+ }
+ else if ((EventPort3 == enEventPort) || (EventPort4 == enEventPort))
+ {
+ M4_AOS->PEVNTTRGSR34 = enTriggerSrc;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Event Port common trigger.
+ **
+ ** \param [in] enEventPort Event port index, This parameter can be
+ ** any value of @ref en_event_port_t
+ ** \param [in] enComTrigger Event port common trigger selection.
+ ** See @ref en_event_port_com_trigger_t for details.
+ ** \param [in] enState Enable or disable the specified common trigger.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void EVENTPORT_ComTriggerCmd(en_event_port_t enEventPort, \
+ en_event_port_com_trigger_t enComTrigger, \
+ en_functional_state_t enState)
+{
+ uint32_t u32ComTrig = (uint32_t)enComTrigger;
+ __IO uint32_t *TRGSELx;
+
+ TRGSELx = (__IO uint32_t *)((uint32_t)&M4_AOS->PEVNTTRGSR12 + (4UL * ((uint32_t)enEventPort/2UL)));
+
+ if (NULL != TRGSELx)
+ {
+ DDL_ASSERT(IS_EP_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (enState == Enable)
+ {
+ *TRGSELx |= (u32ComTrig << 30u);
+ }
+ else
+ {
+ *TRGSELx &= ~(u32ComTrig << 30u);
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read Event Port value after be triggered
+ **
+ ** \param [in] enEventPort Event port index, This parameter can be
+ ** any value of @ref en_event_port_t
+ **
+ ** \retval uint16_t The output port value
+ **
+ ******************************************************************************/
+uint16_t EVENTPORT_GetData(en_event_port_t enEventPort)
+{
+ uint16_t u16Data = 0u;
+ DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
+ switch (enEventPort)
+ {
+ case EventPort1:
+ u16Data = (uint16_t)(M4_AOS->PEVNTIDR1 & 0xFFFFul);
+ break;
+ case EventPort2:
+ u16Data = (uint16_t)(M4_AOS->PEVNTIDR2 & 0xFFFFul);
+ break;
+ case EventPort3:
+ u16Data = (uint16_t)(M4_AOS->PEVNTIDR3 & 0xFFFFul);
+ break;
+ case EventPort4:
+ u16Data = (uint16_t)(M4_AOS->PEVNTIDR4 & 0xFFFFul);
+ break;
+ }
+ return u16Data;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read Event Pin value after triggered
+ **
+ ** \param [in] enEventPort Event port index, This parameter can be
+ ** any value of @ref en_event_port_t
+ ** \param [in] enEventPin GPIO pin index, This parameter can be
+ ** any value of @ref en_event_pin_t
+ ** \retval en_flag_status_t The output port pin value
+ **
+ ******************************************************************************/
+en_flag_status_t EVENTPORT_GetBit(en_event_port_t enEventPort, en_event_pin_t enEventPin)
+{
+ bool bBitValue = false;
+
+ switch (enEventPort)
+ {
+ case EventPort1:
+ bBitValue = M4_AOS->PEVNTIDR1 & enEventPin;
+ break;
+ case EventPort2:
+ bBitValue = M4_AOS->PEVNTIDR2 & enEventPin;
+ break;
+ case EventPort3:
+ bBitValue = M4_AOS->PEVNTIDR3 & enEventPin;
+ break;
+ case EventPort4:
+ bBitValue = M4_AOS->PEVNTIDR4 & enEventPin;
+ break;
+ }
+ return (en_flag_status_t)(bool)((!!bBitValue));
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Event Port Pin
+ **
+ ** \param [in] enEventPort Event port index, This parameter can be
+ ** any value of @ref en_event_port_t
+ ** \param [in] u16EventPin Event pin index, This parameter can be
+ ** any composed value of @ref en_event_pin_t
+ ** \retval Ok Set successful
+ ** ErrorInvalidParameter Event port index invalid
+ **
+ ******************************************************************************/
+en_result_t EVENTPORT_SetBits(en_event_port_t enEventPort, en_event_pin_t u16EventPin)
+{
+ en_result_t enRet = Ok;
+ DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
+
+ switch (enEventPort)
+ {
+ case EventPort1:
+ M4_AOS->PEVNTODR1 |= u16EventPin;
+ break;
+ case EventPort2:
+ M4_AOS->PEVNTODR2 |= u16EventPin;
+ break;
+ case EventPort3:
+ M4_AOS->PEVNTODR3 |= u16EventPin;
+ break;
+ case EventPort4:
+ M4_AOS->PEVNTODR4 |= u16EventPin;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Reset Event Port Pin
+ **
+ ** \param [in] enEventPort Event port index, This parameter can be
+ ** any value of @ref en_event_port_t
+ ** \param [in] u16EventPin Event pin index, This parameter can be
+ ** any composed value of @ref en_event_pin_t
+ ** \retval Ok Reset successful
+ ** ErrorInvalidParameter Event port index invalid
+ **
+ ******************************************************************************/
+en_result_t EVENTPORT_ResetBits(en_event_port_t enEventPort, en_event_pin_t u16EventPin)
+{
+ en_result_t enRet = Ok;
+ DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
+
+ switch (enEventPort)
+ {
+ case EventPort1:
+ M4_AOS->PEVNTODR1 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ break;
+ case EventPort2:
+ M4_AOS->PEVNTODR2 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ break;
+ case EventPort3:
+ M4_AOS->PEVNTODR3 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ break;
+ case EventPort4:
+ M4_AOS->PEVNTODR4 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ return enRet;
+}
+
+//@} // EventPortGroup
+
+/******************************************************************************
+ * EOF (not truncated)
+ *****************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_exint_nmi_swi.c b/lib/hc32f460/driver/src/hc32f460_exint_nmi_swi.c new file mode 100644 index 00000000..71111b25 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_exint_nmi_swi.c @@ -0,0 +1,333 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_exint_nmi_swi.c
+ **
+ ** A detailed description is available at
+ ** @link ExintNmiSwiGroup Exint/Nmi/Swi description @endlink
+ **
+ ** - 2018-10-17 CDT First version for Device Driver Library of exint, Nmi, SW interrupt.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_exint_nmi_swi.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup ExintNmiSwiGroup
+ ******************************************************************************/
+//@{
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+ /*! Parameter validity check for external interrupt channel. */
+#define IS_VALID_CH(x) \
+( ((x) == ExtiCh00) || \
+ ((x) == ExtiCh01) || \
+ ((x) == ExtiCh02) || \
+ ((x) == ExtiCh03) || \
+ ((x) == ExtiCh04) || \
+ ((x) == ExtiCh05) || \
+ ((x) == ExtiCh06) || \
+ ((x) == ExtiCh07) || \
+ ((x) == ExtiCh08) || \
+ ((x) == ExtiCh09) || \
+ ((x) == ExtiCh10) || \
+ ((x) == ExtiCh11) || \
+ ((x) == ExtiCh12) || \
+ ((x) == ExtiCh13) || \
+ ((x) == ExtiCh14) || \
+ ((x) == ExtiCh15))
+
+/*! Parameter validity check for null pointer. */
+#define IS_NULL_POINT(x) (NULL != (x))
+
+/*! Parameter validity check for external interrupt trigger method. */
+#define IS_VALID_LEVEL(x) \
+( ((x) == ExIntLowLevel) || \
+ ((x) == ExIntBothEdge) || \
+ ((x) == ExIntRisingEdge) || \
+ ((x) == ExIntFallingEdge))
+
+/*! Parameter validity check for NMI interrupt source. */
+#define IS_VALID_NMI_SRC(x) \
+( ((x) == NmiSrcNmi) || \
+ ((x) == NmiSrcSwdt) || \
+ ((x) == NmiSrcVdu1) || \
+ ((x) == NmiSrcVdu2) || \
+ ((x) == NmiSrcXtalStop) || \
+ ((x) == NmiSrcSramPE) || \
+ ((x) == NmiSrcSramDE) || \
+ ((x) == NmiSrcMpu) || \
+ ((x) == NmiSrcWdt))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+static func_ptr_t pfnNmiCallback;
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief External Int initialization
+ **
+ ** \param [in] pstcExtiConfig EXTI configure structure
+ **
+ ** \retval Ok EXTI initialized
+ **
+ ******************************************************************************/
+en_result_t EXINT_Init(const stc_exint_config_t *pstcExtiConfig)
+{
+ stc_intc_eirqcr_field_t *EIRQCRx;
+
+ DDL_ASSERT(IS_VALID_CH(pstcExtiConfig->enExitCh));
+
+ EIRQCRx = (stc_intc_eirqcr_field_t *)((uint32_t)(&M4_INTC->EIRQCR0) + \
+ (uint32_t)(4ul * (uint32_t)(pstcExtiConfig->enExitCh)));
+
+ /* Set filter function */
+ EIRQCRx->EFEN = pstcExtiConfig->enFilterEn;
+ EIRQCRx->EISMPCLK = pstcExtiConfig->enFltClk;
+
+ /* Set detection level */
+ EIRQCRx->EIRQTRG = pstcExtiConfig->enExtiLvl;
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get External interrupt request flag
+ **
+ ** \param [in] enExint NMI Int source, This parameter can be
+ ** any value of @ref en_exti_ch_t
+ **
+ ** \retval Set Corresponding Ex.Int request flag be set
+ ** Reset Corresponding Ex.Int request flag not be set
+ **
+ ******************************************************************************/
+en_int_status_t EXINT_IrqFlgGet(en_exti_ch_t enExint)
+{
+ en_int_status_t enRet;
+ DDL_ASSERT(IS_VALID_CH(enExint));
+
+ enRet = (1u == !!(M4_INTC->EIFR & (1ul<<enExint)) ? Set : Reset);
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear External interrupt request flag
+ **
+ ** \param [in] enExint Ext. interrupt channel, This parameter can be
+ ** any value of @ref en_exti_ch_t
+ **
+ ** \retval Ok Interrupt source be cleared
+ **
+ ******************************************************************************/
+en_result_t EXINT_IrqFlgClr(en_exti_ch_t enExint)
+{
+ M4_INTC->EICFR |= (uint32_t)(1ul << enExint);
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief NMI initialization
+ **
+ ** \param [in] pstcNmiConfig NMI configure structure
+ **
+ ** \retval Ok NMI initialized
+ ** ErrorInvalidParameter NMI configuration pointer is null
+ **
+ ******************************************************************************/
+en_result_t NMI_Init(const stc_nmi_config_t *pstcNmiConfig)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != pstcNmiConfig)
+ {
+ /* NMI callback function */
+ pfnNmiCallback = pstcNmiConfig->pfnNmiCallback;
+ /* Set filter function */
+ M4_INTC->NMICR_f.NFEN = pstcNmiConfig->enFilterEn;
+ /* Set filter clock */
+ M4_INTC->NMICR_f.NSMPCLK = pstcNmiConfig->enFilterClk;
+ /* Set detection level */
+ M4_INTC->NMICR_f.NMITRG = pstcNmiConfig->enNmiLvl;
+ /* Set NMI source */
+ M4_INTC->NMIENR = (uint32_t)pstcNmiConfig->u16NmiSrc;
+ enRet = Ok;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Init Non-Maskable Interrupt (NMI)
+ **
+ ** \param None
+ **
+ ** \retval Ok NMI De-initialized
+ **
+ ******************************************************************************/
+en_result_t NMI_DeInit(void)
+{
+ /* Set internal data */
+ pfnNmiCallback = NULL;
+
+ /* clear NMI control register */
+ M4_INTC->NMICR = 0u;
+
+ /* clear NMI enable register */
+ M4_INTC->NMIENR = 0u;
+
+ /* clear all NMI flags */
+ M4_INTC->NMIFR = 0u;
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get NMI interrupt request flag
+ **
+ ** \param [in] enNmiSrc NMI Int source, This parameter can be
+ ** any value of @ref en_nmi_src_t
+ **
+ ** \retval Set Corresponding NMI flag be set
+ ** Reset Corresponding NMI flag not be set
+ **
+ ******************************************************************************/
+en_int_status_t NMI_IrqFlgGet(en_nmi_src_t enNmiSrc)
+{
+ DDL_ASSERT(IS_VALID_NMI_SRC(enNmiSrc));
+
+ en_int_status_t enRet = Reset;
+ switch (enNmiSrc)
+ {
+ case NmiSrcNmi:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.NMIFR);
+ break;
+ case NmiSrcSwdt:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.SWDTFR);
+ break;
+ case NmiSrcVdu1:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.PVD1FR);
+ break;
+ case NmiSrcVdu2:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.PVD2FR);
+ break;
+ case NmiSrcXtalStop:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.XTALSTPFR);
+ break;
+ case NmiSrcSramPE:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.REPFR);
+ break;
+ case NmiSrcSramDE:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.RECCFR);
+ break;
+ case NmiSrcMpu:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.BUSMFR);
+ break;
+ case NmiSrcWdt:
+ enRet = (en_int_status_t)(M4_INTC->NMIFR_f.WDTFR);
+ break;
+ default:
+ break;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear NMI interrupt request flag
+ **
+ ** \param [in] u16NmiSrc NMI Int source, This parameter can be
+ ** any composited value of @ref en_nmi_src_t
+ **
+ ** \retval Ok Interrupt source be cleared
+ **
+ ******************************************************************************/
+en_result_t NMI_IrqFlgClr(uint16_t u16NmiSrc)
+{
+ M4_INTC->NMICFR |= u16NmiSrc;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief ISR for NMI
+ **
+ ******************************************************************************/
+void NMI_IrqHandler(void)
+{
+ DDL_ASSERT(IS_NULL_POINT(pfnNmiCallback));
+
+ pfnNmiCallback();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable Softeware Interrupt (SWI)
+ **
+ * \param [in] u32SwiCh This parameter can be any composited
+ * value of @ref en_swi_ch_t
+ **
+ ** \retval Ok SWI initialized
+ **
+ ******************************************************************************/
+en_result_t SWI_Enable(uint32_t u32SwiCh)
+{
+ M4_INTC->SWIER |= u32SwiCh;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Init Softeware Interrupt (SWI)
+ **
+ * \param [in] u32SwiCh This parameter can be any composited
+ * value of @ref en_swi_ch_t
+ **
+ ** \retval Ok SWI de-initialized
+ **
+ ******************************************************************************/
+en_result_t SWI_Disable(uint32_t u32SwiCh)
+{
+ /* clear software interrupt enable register */
+ M4_INTC->SWIER &= ~u32SwiCh;
+
+ return Ok;
+}
+
+//@} // ExintNmiSwiGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_gpio.c b/lib/hc32f460/driver/src/hc32f460_gpio.c new file mode 100644 index 00000000..d9b31e5e --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_gpio.c @@ -0,0 +1,667 @@ +/******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_gpio.c
+ **
+ ** A detailed description is available at
+ ** @link GpioGroup Gpio description @endlink
+ **
+ ** - 2018-10-12 CDT First version for Device Driver Library of Gpio.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_gpio.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup GpioGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define GPIO_BASE (0x40053800ul)
+#define PODR_BASE (0x0004ul)
+#define POER_BASE (0x0006ul)
+#define POSR_BASE (0x0008ul)
+#define PORR_BASE (0x000Aul)
+#define PCR_BASE (0x0400ul)
+#define PFSR_BASE (0x0402ul)
+
+/*! Parameter validity check for port group. */
+#define IS_VALID_PORT(x) \
+( ((x) == PortA) || \
+ ((x) == PortB) || \
+ ((x) == PortC) || \
+ ((x) == PortD) || \
+ ((x) == PortE) || \
+ ((x) == PortH))
+
+/*! Parameter validity check for pin. */
+#define IS_VALID_PIN(x) \
+( ((x) == Pin00) || \
+ ((x) == Pin01) || \
+ ((x) == Pin02) || \
+ ((x) == Pin03) || \
+ ((x) == Pin04) || \
+ ((x) == Pin05) || \
+ ((x) == Pin06) || \
+ ((x) == Pin07) || \
+ ((x) == Pin08) || \
+ ((x) == Pin09) || \
+ ((x) == Pin10) || \
+ ((x) == Pin11) || \
+ ((x) == Pin12) || \
+ ((x) == Pin13) || \
+ ((x) == Pin14) || \
+ ((x) == Pin15))
+
+/*! Parameter validity check for debug pins. */
+#define IS_VALID_DEBUGPIN(x) ((x) <= 0x1Fu)
+
+/*! Parameter validity check for pin mode. */
+#define IS_VALID_PINMODE(x) \
+( ((x) == Pin_Mode_In) || \
+ ((x) == Pin_Mode_Out) || \
+ ((x) == Pin_Mode_Ana))
+
+/*! Parameter validity check for pin drive capacity. */
+#define IS_VALID_PINDRV(x) \
+( ((x) == Pin_Drv_L) || \
+ ((x) == Pin_Drv_M) || \
+ ((x) == Pin_Drv_H))
+
+/*! Parameter validity check for pin output type. */
+#define IS_VALID_PINTYPE(x) \
+( ((x) == Pin_OType_Cmos) || \
+ ((x) == Pin_OType_Od))
+
+/*! Parameter validity check for pin read wait cycle. */
+#define IS_VALID_READWAIT(x) \
+( ((x) == WaitCycle0) || \
+ ((x) == WaitCycle1) || \
+ ((x) == WaitCycle2) || \
+ ((x) == WaitCycle3))
+
+/*! Parameter validity check for pin function */
+#define IS_VALID_FUNC(x) \
+( ((x) == Func_Gpio) || \
+ (((x) >= Func_Fcmref) && \
+ ((x) <= Func_I2s)) || \
+ ((x) == Func_Evnpt) || \
+ ((x) == Func_Eventout) || \
+ (((x) >= Func_Usart1_Tx) && \
+ ((x) <= Func_I2s2_Ck)))
+
+/*! Parameter validity check for pin sub-function */
+#define IS_VALID_SUBFUNC(x) \
+( ((x) == Func_Gpio) || \
+ ((x) == Func_Fcmref) || \
+ ((x) == Func_Rtcout) || \
+ ((x) == Func_Vcout) || \
+ ((x) == Func_Adtrg) || \
+ ((x) == Func_Mclkout) || \
+ ((x) == Func_Tim4) || \
+ ((x) == Func_Tim6) || \
+ ((x) == Func_Tima0) || \
+ ((x) == Func_Tima1) || \
+ ((x) == Func_Tima2) || \
+ ((x) == Func_Emb) || \
+ ((x) == Func_Usart_Ck) || \
+ ((x) == Func_Spi_Nss) || \
+ ((x) == Func_Qspi) || \
+ ((x) == Func_Key) || \
+ ((x) == Func_Sdio) || \
+ ((x) == Func_I2s) || \
+ ((x) == Func_UsbF) || \
+ ((x) == Func_Evnpt) || \
+ ((x) == Func_Eventout))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Port init
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any composed value of @ref en_pin_t
+ ** \param [in] pstcPortInit Structure pointer of port configuration
+ **
+ ** \retval Ok Port initial successful
+ **
+ ******************************************************************************/
+en_result_t PORT_Init(en_port_t enPort, uint16_t u16Pin, const stc_port_init_t *pstcPortInit)
+{
+ stc_port_pcr_field_t *PCRx;
+ stc_port_pfsr_field_t * PFSRx;
+ uint8_t u8PinPos = 0u;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ DDL_ASSERT(IS_VALID_PINMODE(pstcPortInit->enPinMode));
+ DDL_ASSERT(IS_VALID_PINDRV(pstcPortInit->enPinDrv));
+ DDL_ASSERT(IS_VALID_PINTYPE(pstcPortInit->enPinOType));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enLatch));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enExInt));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enInvert));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enPullUp));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enPinSubFunc));
+
+ PORT_Unlock();
+ for (u8PinPos = 0u; u8PinPos < 16u; u8PinPos ++)
+ {
+ if (u16Pin & (1ul<<u8PinPos))
+ {
+ PCRx = (stc_port_pcr_field_t *)((uint32_t)(&M4_PORT->PCRA0) + \
+ enPort * 0x40ul + u8PinPos * 0x04ul);
+ PFSRx = (stc_port_pfsr_field_t *)((uint32_t)(&M4_PORT->PFSRA0) + \
+ enPort * 0x40ul + u8PinPos * 0x04ul);
+
+ /* Input latch function setting */
+ PCRx->LTE = pstcPortInit->enLatch;
+
+ /* External interrupt input enable setting */
+ PCRx->INTE = pstcPortInit->enExInt;
+
+ /* In_Out invert setting */
+ PCRx->INVE = pstcPortInit->enInvert;
+
+ /* Pin pull-up setting */
+ PCRx->PUU = pstcPortInit->enPullUp;
+
+ /* CMOS/OD output setting */
+ PCRx->NOD = pstcPortInit->enPinOType;
+
+ /* Pin drive mode setting */
+ PCRx->DRV = pstcPortInit->enPinDrv;
+
+ /* Pin mode setting */
+ switch (pstcPortInit->enPinMode)
+ {
+ case Pin_Mode_In:
+ PCRx->DDIS = 0u;
+ PCRx->POUTE = 0u;
+ break;
+ case Pin_Mode_Out:
+ PCRx->DDIS = 0u;
+ PCRx->POUTE = 1u;
+ break;
+ case Pin_Mode_Ana:
+ PCRx->DDIS = 1u;
+ break;
+ default:
+ break;
+ }
+ /* Sub function enable setting */
+ PFSRx->BFE = pstcPortInit->enPinSubFunc;
+ }
+ }
+ PORT_Lock();
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Port de-init
+ **
+ ** \param None
+ **
+ ** \retval Ok GPIO de-initial successful
+ **
+ ******************************************************************************/
+en_result_t PORT_DeInit(void)
+{
+ uint8_t u8PortIdx, u8PinIdx;
+ PORT_Unlock();
+
+ for (u8PortIdx = (uint8_t)PortA; u8PortIdx <= (uint8_t)PortH; u8PortIdx++)
+ {
+ *(uint16_t *)(GPIO_BASE + PODR_BASE + u8PortIdx * 0x10ul) = 0u;
+ *(uint16_t *)(GPIO_BASE + POER_BASE + u8PortIdx * 0x10ul) = 0u;
+ *(uint16_t *)(GPIO_BASE + POSR_BASE + u8PortIdx * 0x10ul) = 0u;
+ *(uint16_t *)(GPIO_BASE + PORR_BASE + u8PortIdx * 0x10ul) = 0u;
+ for (u8PinIdx = 0u; u8PinIdx < 16u; u8PinIdx++)
+ {
+ if (((uint8_t)PortH == u8PortIdx) && (3u == u8PinIdx))
+ {
+ break;
+ }
+ *(uint16_t *)(GPIO_BASE + PCR_BASE + u8PortIdx * 0x40ul + u8PinIdx * 0x4ul) = 0u;
+ *(uint16_t *)(GPIO_BASE + PFSR_BASE + u8PortIdx * 0x40ul + u8PinIdx * 0x4ul) = 0u;
+ }
+ }
+ M4_PORT->PCCR = 0u;
+ M4_PORT->PINAER = 0u;
+ M4_PORT->PSPCR = 0x1Fu;
+
+ PORT_Lock();
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Special control register Setting
+ **
+ ** \param [in] u8DebugPort Debug port setting register, This parameter
+ ** can be any composed value of @ref en_debug_port_t
+ **
+ ** \param [in] enFunc The new state of the debug ports.
+ ** \arg Enable Enable.
+ ** \arg Disable Disable.
+ **
+ ** \retval Ok Debug port set successful
+ **
+ ******************************************************************************/
+en_result_t PORT_DebugPortSetting(uint8_t u8DebugPort, en_functional_state_t enFunc)
+{
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_DEBUGPIN(u8DebugPort));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enFunc));
+
+ PORT_Unlock();
+
+ if (Enable == enFunc)
+ {
+ M4_PORT->PSPCR |= (uint16_t)(u8DebugPort & 0x1Ful);
+ }
+ else
+ {
+ M4_PORT->PSPCR &= (uint16_t)(~(u8DebugPort & 0x1Ful));
+ }
+
+ PORT_Lock();
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Port Public Setting
+ **
+ ** \param [in] pstcPortPubSet Structure pointer of public setting (PCCR)
+ **
+ ** \retval Ok Port public register set successful
+ **
+ ******************************************************************************/
+en_result_t PORT_PubSetting(const stc_port_pub_set_t *pstcPortPubSet)
+{
+ DDL_ASSERT(IS_VALID_FUNC(pstcPortPubSet->enSubFuncSel));
+ DDL_ASSERT(IS_VALID_READWAIT(pstcPortPubSet->enReadWait));
+ PORT_Unlock();
+
+ /* PCCR setting */
+ /* Sub function setting */
+ M4_PORT->PCCR_f.BFSEL = pstcPortPubSet->enSubFuncSel;
+
+ /* PIDRx, PCRxy read wait cycle setting */
+ M4_PORT->PCCR_f.RDWT = pstcPortPubSet->enReadWait;
+
+ PORT_Lock();
+ return Ok;
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief PSPCR, PCCR, PINAER, PCRxy, PFSRxy write enable
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void PORT_Unlock(void)
+{
+ M4_PORT->PWPR = 0xA501u;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPCR, PCCR, PINAER, PCRxy, PFSRxy write disable
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void PORT_Lock(void)
+{
+ M4_PORT->PWPR = 0xA500u;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read Port value
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ **
+ ** \retval uint16_t The output port value
+ **
+ ******************************************************************************/
+uint16_t PORT_GetData(en_port_t enPort)
+{
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ uint32_t *PIDRx;
+ PIDRx = (uint32_t *)((uint32_t)(&M4_PORT->PIDRA) + 0x10u * enPort);
+ return (uint16_t)(*PIDRx);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read Pin value
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] enPin GPIO pin index, This parameter can be
+ ** any value of @ref en_pin_t
+ ** \retval en_flag_status_t The output port pin value
+ **
+ ******************************************************************************/
+en_flag_status_t PORT_GetBit(en_port_t enPort, en_pin_t enPin)
+{
+ uint32_t *PIDRx;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+ DDL_ASSERT(IS_VALID_PIN(enPin));
+
+ PIDRx = (uint32_t *)((uint32_t)(&M4_PORT->PIDRA) + 0x10u * enPort);
+ return (en_flag_status_t)((bool)(!!(*PIDRx & (enPin))));
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Port value
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any composed value of @ref en_pin_t
+ **
+ ** \retval Ok Data be set to corresponding port
+ **
+ ******************************************************************************/
+en_result_t PORT_SetPortData(en_port_t enPort, uint16_t u16Pin)
+{
+ uint16_t *PODRx;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ PODRx = (uint16_t *)((uint32_t)(&M4_PORT->PODRA) + 0x10u * enPort);
+ *PODRx |= u16Pin;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Port value
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any composed value of @ref en_pin_t
+ **
+ ** \retval Ok Data be reset to corresponding port
+ **
+ ******************************************************************************/
+en_result_t PORT_ResetPortData(en_port_t enPort, uint16_t u16Pin)
+{
+ uint16_t *PODRx;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ PODRx = (uint16_t *)((uint32_t)(&M4_PORT->PODRA) + 0x10u * enPort);
+ *PODRx &= (uint16_t)(~u16Pin);
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Port Pin Output enable
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any composed value of @ref en_pin_t
+ ** \param [in] enNewState The new state of pin direction setting
+ ** \retval Ok Set successful to corresponding port/pin
+ **
+ ******************************************************************************/
+en_result_t PORT_OE(en_port_t enPort, uint16_t u16Pin, en_functional_state_t enNewState)
+{
+ uint16_t *POERx;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ POERx = (uint16_t *)((uint32_t)(&M4_PORT->POERA) + 0x10ul * enPort);
+ if (Enable == enNewState)
+ {
+ *POERx |= u16Pin;
+ }
+ else
+ {
+ *POERx &= (uint16_t)(~u16Pin);
+ }
+ return Ok;
+
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Port Pin
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any composed value of @ref en_pin_t
+ ** \retval Ok Set successful to corresponding pins
+ **
+ ******************************************************************************/
+en_result_t PORT_SetBits(en_port_t enPort, uint16_t u16Pin)
+{
+ uint16_t *POSRx;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ POSRx = (uint16_t *)((uint32_t)(&M4_PORT->POSRA) + 0x10u * enPort);
+ *POSRx |= u16Pin;
+ return Ok;
+
+}
+
+/**
+ *******************************************************************************
+ ** \brief Reset Port Pin
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any composed value of @ref en_pin_t
+ ** \retval Ok Set successful to corresponding pins
+ **
+ ******************************************************************************/
+en_result_t PORT_ResetBits(en_port_t enPort, uint16_t u16Pin)
+{
+ uint16_t *PORRx;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ PORRx = (uint16_t *)((uint32_t)(&M4_PORT->PORRA) + 0x10u * enPort);
+ *PORRx |= u16Pin;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Toggle Port Pin
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any composed value of @ref en_pin_t
+ ** \retval Ok Set successful to corresponding pins
+ **
+ ******************************************************************************/
+en_result_t PORT_Toggle(en_port_t enPort, uint16_t u16Pin)
+{
+ uint16_t *POTRx;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+
+ POTRx = (uint16_t *)((uint32_t)(&M4_PORT->POTRA) + 0x10u * enPort);
+ *POTRx |= u16Pin;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set port always ON
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] enNewState The new state of the port always ON function.
+ ** \arg Enable Enable.
+ ** \arg Disable Disable.
+ **
+ ** \retval Ok Set successful to corresponding pins
+ **
+ ******************************************************************************/
+en_result_t PORT_AlwaysOn(en_port_t enPort, en_functional_state_t enNewState)
+{
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ PORT_Unlock();
+
+ if (Enable == enNewState)
+ {
+ M4_PORT->PINAER |= Enable << (uint8_t)enPort;
+ }
+ else
+ {
+ M4_PORT->PINAER &= (uint16_t)(~(((1ul << (uint8_t)enPort)) & 0x1Ful));
+ }
+
+ PORT_Lock();
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Port Pin function
+ **
+ ** \param [in] enPort GPIO port index, This parameter can be
+ ** any value of @ref en_port_t
+ ** \param [in] u16Pin GPIO pin index, This parameter can be
+ ** any value of @ref en_pin_t
+ ** \param [in] enFuncSel Function selection, This parameter can be
+ ** any value of @ref en_port_func_t
+ **
+ ** \param [in] enSubFunc The new state of the gpio sub-function.
+ ** \arg Enable Enable.
+ ** \arg Disable Disable.
+ **
+ ** \retval Ok Set successful to corresponding pins
+ **
+ ******************************************************************************/
+en_result_t PORT_SetFunc(en_port_t enPort, uint16_t u16Pin, en_port_func_t enFuncSel, \
+ en_functional_state_t enSubFunc)
+{
+ stc_port_pfsr_field_t *PFSRx;
+ uint8_t u8PinPos = 0u;
+
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_PORT(enPort));
+ DDL_ASSERT(IS_VALID_FUNC(enFuncSel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enSubFunc));
+
+ PORT_Unlock();
+
+ for (u8PinPos = 0u; u8PinPos < 16u; u8PinPos ++)
+ {
+ if (u16Pin & (uint16_t)(1ul<<u8PinPos))
+ {
+ PFSRx = (stc_port_pfsr_field_t *)((uint32_t)(&M4_PORT->PFSRA0) \
+ + 0x40ul * enPort + 0x4ul * u8PinPos);
+
+ /* main function setting */
+ PFSRx->FSEL = enFuncSel;
+
+ /* sub function enable setting */
+ PFSRx->BFE = (Enable == enSubFunc ? Enable : Disable);
+ }
+ }
+
+ PORT_Lock();
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set global sub-function
+ **
+ ** \param [in] enFuncSel Function selection, This parameter can be
+ ** some values of @ref en_port_func_t, cannot
+ ** large than 15u
+ **
+ ** \retval Ok Set successful to corresponding pins
+ **
+ ******************************************************************************/
+en_result_t PORT_SetSubFunc(en_port_func_t enFuncSel)
+{
+ /* parameter check */
+ DDL_ASSERT(IS_VALID_SUBFUNC(enFuncSel));
+
+ PORT_Unlock();
+
+ M4_PORT->PCCR_f.BFSEL = enFuncSel;
+
+ PORT_Lock();
+ return Ok;
+}
+
+//@} // GpioGroup
+
+/******************************************************************************
+ * EOF (not truncated)
+ *****************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_hash.c b/lib/hc32f460/driver/src/hc32f460_hash.c new file mode 100644 index 00000000..4ae8173d --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_hash.c @@ -0,0 +1,297 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_hash.c
+ **
+ ** A detailed description is available at
+ ** @link HashGroup HASH description @endlink
+ **
+ ** - 2018-10-18 CDT First version for Device Driver Library of HASH.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_hash.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup HashGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/* Constants definitions. */
+#define HASH_GROUP_LEN (64u)
+#define LAST_GROUP_MAX_LEN (56u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+static void HASH_WriteData(const uint8_t *pu8SrcData);
+static void HASH_GetMsgDigest(uint8_t *pu8MsgDigest);
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initialize the HASH.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void HASH_Init(void)
+{
+ /* Stop hash calculating */
+ bM4_HASH_CR_START = 0u;
+}
+
+/**
+ *******************************************************************************
+ ** \brief DeInitialize the HASH.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void HASH_DeInit(void)
+{
+ /* Stop hash calculating */
+ bM4_HASH_CR_START = 0u;
+
+ /* Reset register CR. */
+ M4_HASH->CR = 0u;
+}
+
+/**
+ *******************************************************************************
+ ** \brief HASH(SHA256) processes pu8SrcData.
+ **
+ ** \param [in] pu8SrcData Pointer to the source data buffer (buffer to
+ ** be hashed).
+ **
+ ** \param [in] u32SrcDataSize Length of the input buffer in bytes.
+ **
+ ** \param [out] pu8MsgDigest Pointer to the computed digest. Its size
+ ** must be 32 bytes.
+ **
+ ** \param [in] u32Timeout Timeout value.
+ **
+ ** \retval Ok No error occurred.
+ ** \retval ErrorTimeout HASH works timeout.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t HASH_Start(const uint8_t *pu8SrcData,
+ uint32_t u32SrcDataSize,
+ uint8_t *pu8MsgDigest,
+ uint32_t u32Timeout)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint8_t u8FillBuffer[HASH_GROUP_LEN];
+ uint8_t u8FirstGroup = 0u;
+ uint8_t u8HashEnd = 0u;
+ uint8_t u8DataEndMark = 0u;
+ uint32_t u32Index = 0u;
+ uint32_t u32BitLenHi;
+ uint32_t u32BitLenLo;
+ uint32_t u32HashTimeout;
+ __IO uint32_t u32TimeCount;
+
+ if ((NULL != pu8SrcData) &&
+ (0u != u32SrcDataSize) &&
+ (NULL != pu8MsgDigest) &&
+ (0u != u32Timeout))
+ {
+ /* 10 is the number of required instructions cycles for the below loop statement. */
+ u32HashTimeout = u32Timeout * (SystemCoreClock / 10u / 1000u);
+ u32BitLenHi = (u32SrcDataSize >> 29u) & 0x7u;
+ u32BitLenLo = (u32SrcDataSize << 3u);
+
+ while (1u)
+ {
+ /* Stop hash calculating. */
+ bM4_HASH_CR_START = 0u;
+
+ if (u32SrcDataSize >= HASH_GROUP_LEN)
+ {
+ HASH_WriteData(&pu8SrcData[u32Index]);
+ u32SrcDataSize -= HASH_GROUP_LEN;
+ u32Index += HASH_GROUP_LEN;
+ }
+ else if (u32SrcDataSize >= LAST_GROUP_MAX_LEN)
+ {
+ memset(u8FillBuffer, 0, HASH_GROUP_LEN);
+ memcpy(u8FillBuffer, &pu8SrcData[u32Index], u32SrcDataSize);
+ u8FillBuffer[u32SrcDataSize] = 0x80u;
+ u8DataEndMark = 1u;
+ HASH_WriteData(u8FillBuffer);
+ u32SrcDataSize = 0u;
+ }
+ else
+ {
+ u8HashEnd = 1u;
+ }
+
+ if (u8HashEnd != 0u)
+ {
+ memset(u8FillBuffer, 0, HASH_GROUP_LEN);
+ if (u32SrcDataSize > 0u)
+ {
+ memcpy(u8FillBuffer, &pu8SrcData[u32Index], u32SrcDataSize);
+ }
+ if (u8DataEndMark == 0u)
+ {
+ u8FillBuffer[u32SrcDataSize] = 0x80u;
+ }
+ u8FillBuffer[63u] = (uint8_t)(u32BitLenLo);
+ u8FillBuffer[62u] = (uint8_t)(u32BitLenLo >> 8u);
+ u8FillBuffer[61u] = (uint8_t)(u32BitLenLo >> 16u);
+ u8FillBuffer[60u] = (uint8_t)(u32BitLenLo >> 24u);
+ u8FillBuffer[59u] = (uint8_t)(u32BitLenHi);
+ u8FillBuffer[58u] = (uint8_t)(u32BitLenHi >> 8u);
+ u8FillBuffer[57u] = (uint8_t)(u32BitLenHi >> 16u);
+ u8FillBuffer[56u] = (uint8_t)(u32BitLenHi >> 24u);
+ HASH_WriteData(u8FillBuffer);
+ }
+
+ /* check if first group */
+ if (0u == u8FirstGroup)
+ {
+ u8FirstGroup = 1u;
+ /* Set first group. */
+ bM4_HASH_CR_FST_GRP = 1u;
+ }
+ else
+ {
+ /* Set continuous group. */
+ bM4_HASH_CR_FST_GRP = 0u;
+ }
+
+ /* Start hash calculating. */
+ bM4_HASH_CR_START = 1u;
+
+ u32TimeCount = 0u;
+ enRet = ErrorTimeout;
+ while (u32TimeCount < u32HashTimeout)
+ {
+ if (bM4_HASH_CR_START == 0u)
+ {
+ enRet = Ok;
+ break;
+ }
+ u32TimeCount++;
+ }
+
+ if ((ErrorTimeout == enRet) || (u8HashEnd != 0u))
+ {
+ break;
+ }
+ }
+
+ if (Ok == enRet)
+ {
+ /* HASH calculated done */
+ HASH_GetMsgDigest(pu8MsgDigest);
+ }
+
+ /* Stop hash calculating. */
+ bM4_HASH_CR_START = 0u;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * Function implementation - local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Writes the input buffer in data register.
+ **
+ ** \param [in] pu8SrcData Pointer to source data buffer.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+static void HASH_WriteData(const uint8_t *pu8SrcData)
+{
+ uint8_t i;
+ uint8_t j;
+ uint32_t u32Temp;
+ __IO uint32_t *io32HashDr = &(M4_HASH->DR15);
+
+ for (i = 0u; i < 16u; i++)
+ {
+ j = i * 4u + 3u;
+ u32Temp = (uint32_t)pu8SrcData[j];
+ u32Temp |= ((uint32_t)pu8SrcData[j-1u]) << 8u;
+ u32Temp |= ((uint32_t)pu8SrcData[j-2u]) << 16u;
+ u32Temp |= ((uint32_t)pu8SrcData[j-3u]) << 24u;
+
+ *io32HashDr = u32Temp;
+ io32HashDr++;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Provides the message digest result.
+ **
+ ** \param [out] pu8MsgDigest Pointer to the message digest.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+static void HASH_GetMsgDigest(uint8_t *pu8MsgDigest)
+{
+ uint8_t i;
+ uint8_t j;
+ uint32_t u32Temp;
+ __IO uint32_t *io32HashHr = &(M4_HASH->HR7);
+
+ for (i = 0u; i < 8u; i++)
+ {
+ j = i * 4u + 3u;
+ u32Temp = *io32HashHr;
+
+ pu8MsgDigest[j] = (uint8_t)u32Temp;
+ pu8MsgDigest[j-1u] = (uint8_t)(u32Temp >> 8u);
+ pu8MsgDigest[j-2u] = (uint8_t)(u32Temp >> 16u);
+ pu8MsgDigest[j-3u] = (uint8_t)(u32Temp >> 24u);
+
+ io32HashHr++;
+ }
+}
+
+//@} // HashGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_i2c.c b/lib/hc32f460/driver/src/hc32f460_i2c.c new file mode 100644 index 00000000..d7728ae9 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_i2c.c @@ -0,0 +1,1314 @@ +/******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_i2c.c
+ **
+ ** A detailed description is available at
+ ** @link I2cGroup Inter-Integrated Circuit(I2C) description @endlink
+ **
+ ** - 2018-10-16 CDT First version for Device Driver Library of I2C.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_i2c.h"
+#include "hc32f460_utility.h"
+#include <system_hc32f460.h>
+
+/**
+ *******************************************************************************
+ ** \addtogroup I2cGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/* Config I2C peripheral */
+#define I2C_SRC_CLK (SystemCoreClock >> M4_SYSREG->CMU_SCFGR_f.PCLK3S)
+#define I2C_ANA_FILTER_VALID (1U)
+#define I2C_CLK_TIMEOUT_VALID (1U)
+
+#define I2C_BAUDRATE_MAX (400000ul)
+
+/*! Parameter validity check for unit. */
+#define IS_VALID_UNIT(x) \
+( ((x) == M4_I2C1) || \
+ ((x) == M4_I2C2) || \
+ ((x) == M4_I2C3))
+
+/*! Parameter check for I2C baudrate value !*/
+#define IS_VALID_SPEED(speed) ((speed) <= (I2C_BAUDRATE_MAX))
+
+/*! Parameter check for I2C baudrate calculate prccess !*/
+#define IS_VALID_FDIV(x) \
+( ((x) == I2C_CLK_DIV1) || \
+ ((x) == I2C_CLK_DIV2) || \
+ ((x) == I2C_CLK_DIV4) || \
+ ((x) == I2C_CLK_DIV8) || \
+ ((x) == I2C_CLK_DIV16) || \
+ ((x) == I2C_CLK_DIV32) || \
+ ((x) == I2C_CLK_DIV64) || \
+ ((x) == I2C_CLK_DIV128))
+
+#define IS_VALID_BAUDWIDTH(result) ((result) == true)
+
+/*! Parameter check for Digital filter config !*/
+#define IS_VALID_DIGITAL_FILTER(x) \
+( ((x) == Filter1BaseCycle) || \
+ ((x) == Filter2BaseCycle) || \
+ ((x) == Filter3BaseCycle) || \
+ ((x) == Filter4BaseCycle))
+
+/*! Parameter check for address mode !*/
+#define IS_VALID_ADRMODE(x) \
+( ((x) == Adr7bit) || \
+ ((x) == Adr10bit))
+
+/*! Parameter check for I2C transfer direction !*/
+#define IS_VALID_TRANS_DIR(x) \
+( ((x) == I2CDirReceive) || \
+ ((x) == I2CDirTrans))
+
+/*! Parameter check for Time out control switch !*/
+#define IS_VALID_TIMOUT_SWITCH(x) \
+( ((x) == TimeoutFunOff) || \
+ ((x) == LowTimerOutOn) || \
+ ((x) == HighTimeOutOn) || \
+ ((x) == BothTimeOutOn))
+
+/*! Parameter check for I2C 7 bit address range !*/
+#define IS_VALID_7BIT_ADR(x) ((x) <= 0x7F)
+
+/*! Parameter check for I2C 10 bit address range !*/
+#define IS_VALID_10BIT_ADR(x) ((x) <= 0x3FF)
+
+/*! Parameter check for readable I2C status bit !*/
+#define IS_VALID_RD_STATUS_BIT(x) \
+( ((x) == I2C_SR_STARTF) || \
+ ((x) == I2C_SR_SLADDR0F) || \
+ ((x) == I2C_SR_SLADDR1F) || \
+ ((x) == I2C_SR_TENDF) || \
+ ((x) == I2C_SR_STOPF) || \
+ ((x) == I2C_SR_RFULLF) || \
+ ((x) == I2C_SR_TEMPTYF) || \
+ ((x) == I2C_SR_ARLOF) || \
+ ((x) == I2C_SR_ACKRF) || \
+ ((x) == I2C_SR_NACKF) || \
+ ((x) == I2C_SR_TMOUTF) || \
+ ((x) == I2C_SR_MSL) || \
+ ((x) == I2C_SR_BUSY) || \
+ ((x) == I2C_SR_TRA) || \
+ ((x) == I2C_SR_GENCALLF) || \
+ ((x) == I2C_SR_SMBDEFAULTF) || \
+ ((x) == I2C_SR_SMBHOSTF) || \
+ ((x) == I2C_SR_SMBALRTF))
+
+#define IS_VALID_ACK_CONFIG(x) \
+( ((x) == I2c_ACK) || \
+ ((x) == I2c_NACK))
+
+#define I2C_SCL_HIGHT_LOW_LVL_SUM_MAX ((float32_t)0x1F * (float32_t)2)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Try to wait a status of specified flags
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32Flag specifies the flag to check,
+ ** This parameter can be one of the following values:
+ ** I2C_SR_STARTF
+ ** I2C_SR_SLADDR0F
+ ** I2C_SR_SLADDR1F
+ ** I2C_SR_TENDF
+ ** I2C_SR_STOPF
+ ** I2C_SR_RFULLF
+ ** I2C_SR_TEMPTYF
+ ** I2C_SR_ARLOF
+ ** I2C_SR_ACKRF: ACK status
+ ** I2C_SR_NACKF: NACK Flag
+ ** I2C_SR_TMOUTF
+ ** I2C_SR_MSL
+ ** I2C_SR_BUSY
+ ** I2C_SR_TRA
+ ** I2C_SR_GENCALLF
+ ** I2C_SR_SMBDEFAULTF
+ ** I2C_SR_SMBHOSTF
+ ** I2C_SR_SMBALRTF
+ ** \param [in] enStatus Expected status, This parameter can be one of
+ ** the following values:
+ ** Set
+ ** Reset
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok Successfully gotten the expected status of the specified flags
+ ** \retval ErrorTimeout Failed to get expected status of specified flags.
+ ******************************************************************************/
+en_result_t I2C_WaitStatus(const M4_I2C_TypeDef *pstcI2Cx, uint32_t u32Flag, en_flag_status_t enStatus, uint32_t u32Timeout)
+{
+ en_result_t enRet = ErrorTimeout;
+ uint32_t u32RegStatusBit;
+
+ for(;;)
+ {
+ u32RegStatusBit = (pstcI2Cx->SR & u32Flag);
+ if(((enStatus == Set) && (u32Flag == u32RegStatusBit))
+ || ((enStatus == Reset) && (0UL == u32RegStatusBit)))
+ {
+ enRet = Ok;
+ }
+
+ if((Ok == enRet) || (0UL == u32Timeout))
+ {
+ break;
+ }
+ else
+ {
+ u32Timeout--;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C generate start condition
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState new state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_GenerateStart(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->CR1_f.START = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C generate restart condition
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_GenerateReStart(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->CR1_f.RESTART = enNewState;
+
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C generate stop condition
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_GenerateStop(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->CR1_f.STOP = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the baudrate for I2C peripheral.
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] pstcI2cInit Pointer to I2C config structure @ref stc_i2c_init_t
+ ** 1. pstcI2cInit->u32ClockDiv: Division of i2c source clock, reference as:
+ ** step1: calculate div = (I2cSrcClk/Baudrate/(68+2*dnfsum+SclTime)
+ ** I2cSrcClk -- I2c source clock
+ ** Baudrate -- baudrate of i2c
+ ** SclTime -- =(SCL rising time + SCL falling time)/period of i2c clock
+ ** according to i2c bus hardware parameter.
+ ** dnfsum -- 0 if digital filter off;
+ ** Filter capacity if digital filter on(1 ~ 4)
+ ** step2: chose a division item which is similar and bigger than div,
+ ** from I2C_Clock_Division in i2c driver head file.
+ ** 2. pstcI2cInit->u32Baudrate : Baudrate configuration
+ ** 3. pstcI2cInit->u32SclTime : Indicate SCL pin rising and falling
+ ** time, should be number of T(i2c clock period time)
+ ** @param [out] pf32Error Baudrate error
+ ** @retval en_result_t Enumeration value:
+ ** @arg Ok: Configurate success
+ ** @arg ErrorInvalidParameter: Invalid parameter
+ ******************************************************************************/
+en_result_t I2C_BaudrateConfig(M4_I2C_TypeDef* pstcI2Cx, const stc_i2c_init_t* pstcI2cInit, float32_t *pf32Error)
+{
+ en_result_t enRet = Ok;
+ uint32_t I2cSrcClk;
+ uint32_t I2cDivClk;
+ uint32_t SclCnt;
+ uint32_t Baudrate;
+ uint32_t dnfsum = 0UL;
+ uint32_t divsum = 2UL;
+ uint32_t TheoryBaudrate;
+ float32_t WidthTotal;
+ float32_t SumTotal;
+ float32_t WidthHL;
+ float32_t fErr = 0.0F;
+
+ if ((NULL == pstcI2cInit) || (NULL == pf32Error))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_SPEED(pstcI2cInit->u32Baudrate));
+ DDL_ASSERT(IS_VALID_FDIV(pstcI2cInit->u32ClockDiv));
+
+ /* Get configuration for i2c */
+ I2cSrcClk = I2C_SRC_CLK;
+ I2cDivClk = 1ul << pstcI2cInit->u32ClockDiv;
+ SclCnt = pstcI2cInit->u32SclTime;
+ Baudrate = pstcI2cInit->u32Baudrate;
+
+ /* Judge digital filter status */
+ if(1u == pstcI2Cx->FLTR_f.DNFEN)
+ {
+ dnfsum = pstcI2Cx->FLTR_f.DNF+1ul;
+ }
+
+ /* Judge if clock divider on*/
+ if(I2C_CLK_DIV1 == pstcI2cInit->u32ClockDiv)
+ {
+ divsum = 3ul;
+ }
+
+ WidthTotal = (float32_t)I2cSrcClk / (float32_t)Baudrate / (float32_t)I2cDivClk;
+ SumTotal = (2.0F*(float32_t)divsum) + (2.0F*(float32_t)dnfsum) + (float32_t)SclCnt;
+ WidthHL = WidthTotal - SumTotal;
+
+ /* Integer for WidthTotal, rounding off */
+ if ((WidthTotal - (float32_t)((uint32_t)WidthTotal)) >= 0.5F)
+ {
+ WidthTotal = (float32_t)((uint32_t)WidthTotal) + 1.0F;
+ }
+ else
+ {
+ WidthTotal = (float32_t)((uint32_t)WidthTotal);
+ }
+
+ if(WidthTotal <= SumTotal)
+ {
+ /* Err, Should set a smaller division value for pstcI2cInit->u32ClockDiv */
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ if(WidthHL > I2C_SCL_HIGHT_LOW_LVL_SUM_MAX)
+ {
+ /* Err, Should set a bigger division value for pstcI2cInit->u32ClockDiv */
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ TheoryBaudrate = I2cSrcClk / (uint32_t)WidthTotal / I2cDivClk;
+ fErr = ((float32_t)Baudrate - (float32_t)TheoryBaudrate) / (float32_t)TheoryBaudrate;
+
+ /* Write register */
+ pstcI2Cx->CCR_f.FREQ = pstcI2cInit->u32ClockDiv;
+ pstcI2Cx->CCR_f.SLOWW = (uint32_t)WidthHL/2u;
+ pstcI2Cx->CCR_f.SHIGHW = (uint32_t)WidthHL - ((uint32_t)WidthHL)/2u;
+ }
+ }
+ }
+
+ if((NULL != pf32Error) && (Ok == enRet))
+ {
+ *pf32Error = fErr;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-initialize I2C unit
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \retval Ok Process finished.
+ ******************************************************************************/
+en_result_t I2C_DeInit(M4_I2C_TypeDef* pstcI2Cx)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ /* Reset peripheral register and internal status*/
+ pstcI2Cx->CR1_f.PE = 0u;
+ pstcI2Cx->CR1_f.SWRST = 1u;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize I2C peripheral according to the structure
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] pstcI2cInit Pointer to I2C config structure @ref stc_i2c_init_t
+ ** 1. pstcI2cInit->u32ClockDiv: Division of i2c source clock, reference as:
+ ** step1: calculate div = (I2cSrcClk/Baudrate/(68+2*dnfsum+SclTime)
+ ** I2cSrcClk -- I2c source clock
+ ** Baudrate -- baudrate of i2c
+ ** SclTime -- =(SCL rising time + SCL falling time)/period of i2c clock
+ ** according to i2c bus hardware parameter.
+ ** dnfsum -- 0 if digital filter off;
+ ** Filter capacity if digital filter on(1 ~ 4)
+ ** step2: chose a division item which is similar and bigger than div,
+ ** from I2C_Clock_Division in i2c driver head file.
+ ** 2. pstcI2cInit->u32Baudrate : Baudrate configuration
+ ** 3. pstcI2cInit->u32SclTime : Indicate SCL pin rising and falling
+ ** time, should be number of T(i2c clock period time)
+ ** @param [out] pf32Error Baudrate error
+ ** @retval en_result_t Enumeration value:
+ ** @arg Ok: Configurate success
+ ** @arg ErrorInvalidParameter: Invalid parameter
+ ******************************************************************************/
+en_result_t I2C_Init(M4_I2C_TypeDef* pstcI2Cx, const stc_i2c_init_t* pstcI2cInit, float32_t *pf32Error)
+{
+ en_result_t enRes = Ok;
+ if((NULL == pstcI2cInit) || (NULL == pstcI2Cx))
+ {
+ enRes = ErrorInvalidParameter;
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_SPEED(pstcI2cInit->u32Baudrate));
+ DDL_ASSERT(IS_VALID_FDIV(pstcI2cInit->u32ClockDiv));
+
+ /* Register and internal status reset */
+ pstcI2Cx->CR1_f.PE = 0u;
+ pstcI2Cx->CR1_f.SWRST = 1u;
+
+ pstcI2Cx->CR1_f.PE = 1u;
+
+ enRes = I2C_BaudrateConfig(pstcI2Cx, pstcI2cInit, pf32Error);
+
+ pstcI2Cx->CR1_f.ENGC = 0u;
+ pstcI2Cx->CR1_f.SWRST = 0u;
+ pstcI2Cx->CR1_f.PE = 0u;
+ }
+ return enRes;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C slave address0 config
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \param [in] enAdrMode Address mode,can be Adr7bit or Adr10bit
+ ** \param [in] u32Adr The slave address
+ ** \retval None
+ ******************************************************************************/
+void I2C_SlaveAdr0Config(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState, en_address_bit_t enAdrMode, uint32_t u32Adr)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+ DDL_ASSERT(IS_VALID_ADRMODE(enAdrMode));
+
+ pstcI2Cx->SLR0_f.SLADDR0EN = enNewState;
+ pstcI2Cx->SLR0_f.ADDRMOD0 = enAdrMode;
+ if(Adr7bit == enAdrMode)
+ {
+ DDL_ASSERT(IS_VALID_7BIT_ADR(u32Adr));
+ pstcI2Cx->SLR0_f.SLADDR0 = u32Adr << 1ul;
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_10BIT_ADR(u32Adr));
+ pstcI2Cx->SLR0_f.SLADDR0 = u32Adr;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C slave address1 config
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \param [in] enAdrMode Address mode,can be Adr7bit or Adr10bit
+ ** \param [in] u32Adr The slave address
+ ** \retval None
+ ******************************************************************************/
+void I2C_SlaveAdr1Config(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState, en_address_bit_t enAdrMode, uint32_t u32Adr)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+ DDL_ASSERT(IS_VALID_ADRMODE(enAdrMode));
+
+ pstcI2Cx->SLR1_f.SLADDR1EN = enNewState;
+ pstcI2Cx->SLR1_f.ADDRMOD1 = enAdrMode;
+ if(Adr7bit == enAdrMode)
+ {
+ DDL_ASSERT(IS_VALID_7BIT_ADR(u32Adr));
+ pstcI2Cx->SLR1_f.SLADDR1 = u32Adr << 1ul;
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_10BIT_ADR(u32Adr));
+ pstcI2Cx->SLR1_f.SLADDR1 = u32Adr;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_Cmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->CR1_f.PE = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C fast ACK function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the fast ACK function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_FastAckCmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(Enable == enNewState)
+ {
+ pstcI2Cx->CR3_f.FACKEN = 0ul;
+ }
+ else
+ {
+ pstcI2Cx->CR3_f.FACKEN = 1ul;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C bus wait function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the fast ACK function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_BusWaitCmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(Enable == enNewState)
+ {
+ pstcI2Cx->CR4_f.BUSWAIT = 1ul;
+ }
+ else
+ {
+ pstcI2Cx->CR4_f.BUSWAIT = 0ul;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C SMBUS function configuration
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] pstcI2C_SmbusInitStruct
+ ** Pointer to I2C SMBUS configuration structure
+ ** \retval Ok Process finished.
+ ** \retval ErrorInvalidParameter Parameter error.
+ ******************************************************************************/
+en_result_t I2C_SmbusConfig(M4_I2C_TypeDef* pstcI2Cx, const stc_i2c_smbus_init_t* pstcI2C_SmbusInitStruct)
+{
+ en_result_t enRet = Ok;
+ if(NULL != pstcI2C_SmbusInitStruct)
+ {
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcI2C_SmbusInitStruct->enHostAdrMatchFunc));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcI2C_SmbusInitStruct->enDefaultAdrMatchFunc));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcI2C_SmbusInitStruct->enAlarmAdrMatchFunc));
+
+ pstcI2Cx->CR1_f.SMBHOSTEN = pstcI2C_SmbusInitStruct->enHostAdrMatchFunc;
+ pstcI2Cx->CR1_f.SMBDEFAULTEN = pstcI2C_SmbusInitStruct->enDefaultAdrMatchFunc;
+ pstcI2Cx->CR1_f.SMBALRTEN = pstcI2C_SmbusInitStruct->enAlarmAdrMatchFunc;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C SMBUS function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_SmBusCmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->CR1_f.SMBUS = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C digital filter function configuration
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enDigiFilterMode Chose the digital filter mode, This parameter
+ ** can be one of the following values:
+ ** Filter1BaseCycle
+ ** Filter2BaseCycle
+ ** Filter3BaseCycle
+ ** Filter4BaseCycle
+ ** \retval None
+ ******************************************************************************/
+void I2C_DigitalFilterConfig(M4_I2C_TypeDef* pstcI2Cx, en_i2c_digital_filter_mode_t enDigiFilterMode)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_DIGITAL_FILTER(enDigiFilterMode));
+
+ pstcI2Cx->FLTR_f.DNF = enDigiFilterMode;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C digital filter function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_DigitalFilterCmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->FLTR_f.DNFEN = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C analog filter function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_AnalogFilterCmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->FLTR_f.ANFEN = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C general call function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_GeneralCallCmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->CR1_f.ENGC = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C status bit get
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32StatusBit specifies the flag to check,
+ ** This parameter can be one of the following values:
+ ** I2C_SR_STARTF
+ ** I2C_SR_SLADDR0F
+ ** I2C_SR_SLADDR1F
+ ** I2C_SR_TENDF
+ ** I2C_SR_STOPF
+ ** I2C_SR_RFULLF
+ ** I2C_SR_TEMPTYF
+ ** I2C_SR_ARLOF
+ ** I2C_SR_ACKRF: ACK status
+ ** I2C_SR_NACKF: NACK Flag
+ ** I2C_SR_TMOUTF
+ ** I2C_SR_MSL
+ ** I2C_SR_BUSY
+ ** I2C_SR_TRA
+ ** I2C_SR_GENCALLF
+ ** I2C_SR_SMBDEFAULTF
+ ** I2C_SR_SMBHOSTF
+ ** I2C_SR_SMBALRTF
+ ** \retval en_flag_status_t The status of the I2C status flag, may be Set or Reset.
+ ******************************************************************************/
+en_flag_status_t I2C_GetStatus(M4_I2C_TypeDef* pstcI2Cx, uint32_t u32StatusBit)
+{
+ en_flag_status_t enRet = Reset;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_RD_STATUS_BIT(u32StatusBit));
+
+ if(0ul != (pstcI2Cx->SR & u32StatusBit))
+ {
+ enRet = Set;
+ }
+ else
+ {
+ enRet = Reset;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear I2C status flag
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32StatusBit specifies the flag to clear,
+ ** This parameter can be any combination of the following values:
+ ** I2C_CLR_STARTFCLR
+ ** I2C_CLR_SLADDR0FCLR
+ ** I2C_CLR_SLADDR1FCLR
+ ** I2C_CLR_TENDFCLR
+ ** I2C_CLR_STOPFCLR
+ ** I2C_CLR_RFULLFCLR
+ ** I2C_CLR_TEMPTYFCLR
+ ** I2C_CLR_ARLOFCLR
+ ** I2C_CLR_NACKFCLR
+ ** I2C_CLR_TMOUTFCLR
+ ** I2C_CLR_GENCALLFCLR
+ ** I2C_CLR_SMBDEFAULTFCLR
+ ** I2C_CLR_SMBHOSTFCLR
+ ** I2C_CLR_SMBALRTFCLR
+ ** \retval None
+ ******************************************************************************/
+void I2C_ClearStatus(M4_I2C_TypeDef* pstcI2Cx, uint32_t u32StatusBit)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ pstcI2Cx->CLR |= (u32StatusBit & I2C_CLR_MASK);
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C software reset function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_SoftwareResetCmd(M4_I2C_TypeDef* pstcI2Cx, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ pstcI2Cx->CR1_f.SWRST = enNewState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C interrupt function command
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32IntEn Specifies the I2C interrupts sources to be configuration
+ ** This parameter can be any combination of the following values:
+ ** I2C_CR2_STARTIE
+ ** I2C_CR2_SLADDR0EN
+ ** I2C_CR2_SLADDR1EN
+ ** I2C_CR2_TENDIE
+ ** I2C_CR2_STOPIE
+ ** I2C_CR2_RFULLIE
+ ** I2C_CR2_TEMPTYIE
+ ** I2C_CR2_ARLOIE
+ ** I2C_CR2_NACKIE
+ ** I2C_CR2_TMOURIE
+ ** I2C_CR2_GENCALLIE
+ ** I2C_CR2_SMBDEFAULTIE
+ ** I2C_CR2_SMBHOSTIE
+ ** I2C_CR2_SMBALRTIE
+ ** \param [in] enNewState New state of the I2Cx function, can be
+ ** Disable or Enable the function
+ ** \retval None
+ ******************************************************************************/
+void I2C_IntCmd(M4_I2C_TypeDef* pstcI2Cx, uint32_t u32IntEn, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(Enable == enNewState)
+ {
+ pstcI2Cx->CR2 |= u32IntEn;
+ }
+ else
+ {
+ pstcI2Cx->CR2 &= ~u32IntEn;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C write data register
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u8Data The data to be send
+ ** \retval None
+ ******************************************************************************/
+void I2C_WriteData(M4_I2C_TypeDef* pstcI2Cx, uint8_t u8Data)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ pstcI2Cx->DTR = u8Data;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C read data register
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \retval uint8_t The value of the received data
+ ******************************************************************************/
+uint8_t I2C_ReadData(M4_I2C_TypeDef* pstcI2Cx)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ return pstcI2Cx->DRR;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C ACK status configuration
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32AckConfig I2C ACK configurate.
+ ** I2c_ACK: Send ACK after date received.
+ ** I2c_NACK: Send NACK after date received.
+ ** \retval None
+ ******************************************************************************/
+void I2C_AckConfig(M4_I2C_TypeDef* pstcI2Cx, en_i2c_ack_config_t u32AckConfig)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_ACK_CONFIG(u32AckConfig));
+
+ pstcI2Cx->CR1_f.ACK = u32AckConfig;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2C clock timer out function config
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] pstcTimoutInit Pointer to I2C timeout function structure
+ ** \retval Ok Process finished.
+ ** \retval ErrorInvalidParameter Parameter error.
+ ******************************************************************************/
+en_result_t I2C_ClkTimeOutConfig(M4_I2C_TypeDef* pstcI2Cx, const stc_clock_timeout_init_t* pstcTimoutInit)
+{
+ en_result_t enRet = Ok;
+ if(NULL != pstcTimoutInit)
+ {
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_TIMOUT_SWITCH(pstcTimoutInit->enClkTimeOutSwitch));
+
+ pstcI2Cx->SLTR_f.TOUTHIGH = pstcTimoutInit->u16TimeOutHigh;
+ pstcI2Cx->SLTR_f.TOUTLOW = pstcTimoutInit->u16TimeOutLow;
+
+ pstcI2Cx->CR3 &= ~0x00000007ul;
+ pstcI2Cx->CR3 |= pstcTimoutInit->enClkTimeOutSwitch;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx start
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok Start success
+ ** \retval ErrorTimeout Start time out
+ ******************************************************************************/
+en_result_t I2C_Start(M4_I2C_TypeDef* pstcI2Cx, uint32_t u32Timeout)
+{
+ en_result_t enRet;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_BUSY, Reset, u32Timeout);
+
+ if(Ok == enRet)
+ {
+ /* generate start signal */
+ I2C_GenerateStart(pstcI2Cx, Enable);
+ /* Judge if start success*/
+ enRet = I2C_WaitStatus(pstcI2Cx, (I2C_SR_BUSY | I2C_SR_STARTF), Set, u32Timeout);
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx restart
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok Restart successfully
+ ** \retval ErrorTimeout Restart time out
+ ******************************************************************************/
+en_result_t I2C_Restart(M4_I2C_TypeDef* pstcI2Cx, uint32_t u32Timeout)
+{
+ en_result_t enRet;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ /* Clear start status flag */
+ I2C_ClearStatus(pstcI2Cx, I2C_CLR_STARTFCLR);
+ /* Send restart condition */
+ I2C_GenerateReStart(pstcI2Cx, Enable);
+ /* Judge if start success*/
+ enRet = I2C_WaitStatus(pstcI2Cx, (I2C_SR_BUSY | I2C_SR_STARTF), Set, u32Timeout);
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx send address
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u8Addr The address to be sent
+ ** \param [in] enDir Can be I2CDirTrans or I2CDirReceive
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok: Send successfully
+ ** \retval Error: Send suscessfully and receive NACK
+ ** \retval ErrorTimeout: Send address time out
+ ******************************************************************************/
+en_result_t I2C_TransAddr(M4_I2C_TypeDef* pstcI2Cx, uint8_t u8Addr, en_trans_direction_t enDir, uint32_t u32Timeout)
+{
+ en_result_t enRet;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_7BIT_ADR(u8Addr));
+ DDL_ASSERT(IS_VALID_TRANS_DIR(enDir));
+
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TEMPTYF, Set, u32Timeout);
+
+ if(Ok == enRet)
+ {
+ /* Send I2C address */
+ I2C_WriteData(pstcI2Cx, (u8Addr << 1u) | (uint8_t)enDir);
+
+ if(I2CDirTrans == enDir)
+ {
+ /* If in master transfer process, Need wait transfer end */
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TENDF, Set, u32Timeout);
+ }
+ else
+ {
+ /* If in master receive process, Need wait TRA flag */
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TRA, Reset, u32Timeout);
+ }
+
+ if(enRet == Ok)
+ {
+ /* If receive NACK */
+ if(I2C_GetStatus(pstcI2Cx, I2C_SR_ACKRF) == Set)
+ {
+ enRet = Error;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx send address 10 bit
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u16Addr The address to be sent
+ ** \param [in] enDir Can be I2CDirTrans or I2CDirReceive
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok: Send successfully
+ ** \retval Error: Send suscessfully and receive NACK
+ ** \retval ErrorTimeout: Send address time out
+ ******************************************************************************/
+en_result_t I2C_Trans10BitAddr(M4_I2C_TypeDef* pstcI2Cx, uint16_t u16Addr, en_trans_direction_t enDir, uint32_t u32Timeout)
+{
+ en_result_t enRet;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+ DDL_ASSERT(IS_VALID_10BIT_ADR(u16Addr));
+ DDL_ASSERT(IS_VALID_TRANS_DIR(enDir));
+
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TEMPTYF, Set, u32Timeout);
+ if(Ok == enRet)
+ {
+ /* Write 11110 + SLA(bit9:8) + W#(1bit) */
+ I2C_WriteData(pstcI2Cx, (uint8_t)((u16Addr>>7u) & 0x06u) | 0xF0u | (uint8_t)I2CDirTrans);
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TENDF, Set, u32Timeout);
+
+ if(Ok == enRet)
+ {
+ /* If receive ACK */
+ if(I2C_GetStatus(pstcI2Cx, I2C_SR_ACKRF) == Reset)
+ {
+ /* Write SLA(bit7:0)*/
+ I2C_WriteData(pstcI2Cx, (uint8_t)(u16Addr & 0xFFu));
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TENDF, Set, u32Timeout);
+
+ if(Ok == enRet)
+ {
+ if(I2C_GetStatus(pstcI2Cx, I2C_SR_ACKRF) != Reset)
+ {
+ enRet = Error;
+ }
+ }
+ }
+ else
+ {
+ enRet = Error;
+ }
+ }
+ }
+
+ if((I2CDirReceive == enDir) && (Ok == enRet))
+ {
+ /* Restart */
+ I2C_ClearStatus(pstcI2Cx, I2C_CLR_STARTFCLR);
+ I2C_GenerateReStart(pstcI2Cx, Enable);
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_STARTF, Set, u32Timeout);
+
+ if(Ok == enRet)
+ {
+ /* Write 11110 + SLA(bit9:8) + R(1bit) */
+ I2C_WriteData(pstcI2Cx, (uint8_t)((u16Addr>>7u) & 0x06u) | 0xF0u | (uint8_t)I2CDirReceive);
+ /* If in master receive process, Need wait TRA flag */
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TRA, Reset, u32Timeout);
+
+ if(Ok == enRet)
+ {
+ /* If receive NACK */
+ if(I2C_GetStatus(pstcI2Cx, I2C_SR_ACKRF) != Reset)
+ {
+ enRet = Error;
+ }
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx send data
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] au8TxData The data array to be sent
+ ** \param [in] u32Size Number of data in array pau8TxData
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok: Send successfully
+ ** \retval ErrorTimeout: Send data time out
+ ** \retval ErrorInvalidParameter: au8TxData is NULL
+ ******************************************************************************/
+en_result_t I2C_TransData(M4_I2C_TypeDef* pstcI2Cx, uint8_t const au8TxData[], uint32_t u32Size, uint32_t u32Timeout)
+{
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ en_result_t enRet = Ok;
+ __IO uint32_t u32Cnt = 0ul;
+
+ if(au8TxData != NULL)
+ {
+ while((u32Cnt != u32Size) && (enRet == Ok))
+ {
+ /* Wait tx buffer empty */
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TEMPTYF, Set, u32Timeout);
+
+ if(enRet == Ok)
+ {
+ /* Send one byte data */
+ I2C_WriteData(pstcI2Cx, au8TxData[u32Cnt]);
+
+ /* Wait transfer end */
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TENDF, Set, u32Timeout);
+
+ /* If receive NACK in slave tx mode */
+ if(I2C_GetStatus(pstcI2Cx, I2C_SR_NACKF) == Set)
+ {
+ I2C_ClearStatus(pstcI2Cx, I2C_CLR_NACKFCLR);
+ /* Exit data transfer */
+ break;
+ }
+
+ u32Cnt++;
+ }
+ }
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx receive data
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [out] au8RxData Array to hold the received data
+ ** \param [in] u32Size Number of data to be received
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok: Receive successfully
+ ** \retval ErrorTimeout: Receive data time out
+ ** \retval ErrorInvalidParameter: au8RxData is NULL
+ ******************************************************************************/
+en_result_t I2C_ReceiveData(M4_I2C_TypeDef* pstcI2Cx, uint8_t au8RxData[], uint32_t u32Size, uint32_t u32Timeout)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ if(au8RxData != NULL)
+ {
+ uint32_t u32FastAckDis = (pstcI2Cx->CR3_f.FACKEN);
+ for(uint32_t i=0ul; i<u32Size; i++)
+ {
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_RFULLF, Set, u32Timeout);
+
+ if(0ul == u32FastAckDis)
+ {
+ if((u32Size >= 2ul) && (i == (u32Size - 2ul)))
+ {
+ I2C_AckConfig(pstcI2Cx, I2c_NACK);
+ }
+ }
+ else
+ {
+ if(i != (u32Size - 1ul))
+ {
+ I2C_AckConfig(pstcI2Cx, I2c_ACK);
+ }
+ else
+ {
+ I2C_AckConfig(pstcI2Cx, I2c_NACK);
+ }
+ }
+
+ if(enRet == Ok)
+ {
+ /* read data from register */
+ au8RxData[i] = I2C_ReadData(pstcI2Cx);
+ }
+ else
+ {
+ break;
+ }
+ }
+ I2C_AckConfig(pstcI2Cx, I2c_ACK);
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx master receive data and stop
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [out] au8RxData Array to hold the received data
+ ** \param [in] u32Size Number of data to be received
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok: Receive successfully
+ ** \retval ErrorTimeout: Receive data time out
+ ** \retval ErrorInvalidParameter: au8RxData is NULL
+ ******************************************************************************/
+en_result_t I2C_MasterDataReceiveAndStop(M4_I2C_TypeDef* pstcI2Cx, uint8_t au8RxData[], uint32_t u32Size, uint32_t u32Timeout)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ if(au8RxData != NULL)
+ {
+ uint32_t u32FastAckDis = (pstcI2Cx->CR3_f.FACKEN);
+ for(uint32_t i=0ul; i<u32Size; i++)
+ {
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_RFULLF, Set, u32Timeout);
+
+ if(0ul == u32FastAckDis)
+ {
+ if((u32Size >= 2ul) && (i == (u32Size - 2ul)))
+ {
+ I2C_AckConfig(pstcI2Cx, I2c_NACK);
+ }
+ }
+ else
+ {
+ if(i != (u32Size - 1ul))
+ {
+ I2C_AckConfig(pstcI2Cx, I2c_ACK);
+ }
+ else
+ {
+ I2C_AckConfig(pstcI2Cx, I2c_NACK);
+ }
+ }
+
+ if(enRet == Ok)
+ {
+ /* Stop before read last data */
+ if(i == (u32Size - 1ul))
+ {
+ I2C_ClearStatus(pstcI2Cx, I2C_CLR_STOPFCLR);
+ I2C_GenerateStop(pstcI2Cx, Enable);
+ }
+
+ /* read data from register */
+ au8RxData[i] = I2C_ReadData(pstcI2Cx);
+
+ /* Wait stop flag after DRR read */
+ if(i == (u32Size - 1ul))
+ {
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_STOPF, Set, u32Timeout);
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ I2C_AckConfig(pstcI2Cx, I2c_ACK);
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief I2Cx stop
+ ** \param [in] pstcI2Cx Pointer to the I2C peripheral register, can
+ ** be M4_I2C1,M4_I2C2 or M4_I2C3.
+ ** \param [in] u32Timeout Maximum count of trying to get a status of a
+ ** flag in status register
+ ** \retval Ok: Receive successfully
+ ** \retval ErrorTimeout: Receive data time out
+ ******************************************************************************/
+en_result_t I2C_Stop(M4_I2C_TypeDef* pstcI2Cx, uint32_t u32Timeout)
+{
+ en_result_t enRet;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
+
+ /* Clear stop flag */
+ while((Set == I2C_GetStatus(pstcI2Cx, I2C_SR_STOPF)) && (u32Timeout > 0ul))
+ {
+ I2C_ClearStatus(pstcI2Cx, I2C_CLR_STOPFCLR);
+ u32Timeout--;
+ }
+ I2C_GenerateStop(pstcI2Cx, Enable);
+ /* Wait stop flag */
+ enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_STOPF, Set, u32Timeout);
+
+ return enRet;
+}
+
+//@} // I2cGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_i2s.c b/lib/hc32f460/driver/src/hc32f460_i2s.c new file mode 100644 index 00000000..ece22529 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_i2s.c @@ -0,0 +1,433 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_i2s.c
+ **
+ ** A detailed description is available at
+ ** @link I2sGroup Inter-IC Sound Bus description @endlink
+ **
+ ** - 2018-10-28 CDT First version for Device Driver Library of I2S.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_i2s.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup I2sGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for I2S register pointer */
+#define IS_VALID_I2S_REG(x) \
+( (M4_I2S1 == (x)) || \
+ (M4_I2S2 == (x)) || \
+ (M4_I2S3 == (x)) || \
+ (M4_I2S4 == (x)))
+
+/*!< Parameter valid check for I2S function */
+#define IS_VALID_I2S_FUNCTION(x) \
+( (TxEn == (x)) || \
+ (TxIntEn == (x)) || \
+ (RxEn == (x)) || \
+ (RxIntEn == (x)) || \
+ (ErrIntEn == (x)))
+
+/*!< Parameter valid check for I2S status bits */
+#define IS_VALID_I2S_STATUS(x) \
+( (TxBufAlarmFlag == (x)) || \
+ (RxBufAlarmFlag == (x)) || \
+ (TxBufEmptFlag == (x)) || \
+ (TxBufFullFlag == (x)) || \
+ (RxBufEmptFlag == (x)) || \
+ (RxBufFullFlag == (x)))
+
+/*!< Parameter valid check for I2S error flag */
+#define IS_VALID_I2S_ERR_FLAG(x) \
+( (ClrTxErrFlag == (x)) || \
+ (ClrRxErrFlag == (x)))
+
+/*!< Parameter valid check for I2S mode */
+#define IS_VALID_I2S_MODE(x) \
+( (I2sMaster == (x)) || \
+ (I2sSlave == (x)))
+
+/*!< Parameter valid check for I2S full duplex mode */
+#define IS_VALID_I2S_DUPLEX_MODE(x) \
+( (I2s_HalfDuplex == (x)) || \
+ (I2s_FullDuplex == (x)))
+
+/*!< Parameter valid check for I2S standard */
+#define IS_VALID_I2S_STANDARD(x) \
+( (Std_Philips == (x)) || \
+ (Std_MSBJust == (x)) || \
+ (Std_LSBJust == (x)) || \
+ (Std_PCM == (x)))
+
+/*!< Parameter valid check for I2S data length */
+#define IS_VALID_I2S_DATA_LEN(x) \
+( (I2s_DataLen_16Bit == (x)) || \
+ (I2s_DataLen_24Bit == (x)) || \
+ (I2s_DataLen_32Bit == (x)))
+
+/*!< Parameter valid check for I2S channel data length */
+#define IS_VALID_I2S_CHANNEL_LEN(x) \
+( (I2s_ChLen_16Bit == (x)) || \
+ (I2s_ChLen_32Bit == (x)))
+
+/*!< Parameter valid check for I2S MCK output config */
+#define IS_VALID_I2S_MCKOUT(x) \
+( (Disable == (x)) || \
+ (Enable == (x)))
+
+/*!< Parameter valid check for I2S EXCK config */
+#define IS_VALID_I2S_EXCK(x) \
+( (Disable == (x)) || \
+ (Enable == (x)))
+
+/*!< Parameter valid check for I2S audio frequecy */
+#define IS_I2S_AUDIO_FREQ(FREQ) \
+( (((FREQ) >= I2S_AudioFreq_8k) && ((FREQ) <= I2S_AudioFreq_192k)) || \
+ ((FREQ) == I2S_AudioFreq_Default))
+
+/*! I2S registers reset value */
+#define I2S_REG_CTRL_RESET_VALUE (0x00002200ul)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief I2S function command
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \param [in] enFunc I2S function
+ ** \arg Refer @ref en_i2s_func_t
+ ** \param [in] enNewState New status
+ ** \arg Refer @ref en_functional_state_t
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void I2S_FuncCmd(M4_I2S_TypeDef* pstcI2sReg, en_i2s_func_t enFunc,
+ en_functional_state_t enNewState)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+ DDL_ASSERT(IS_VALID_I2S_FUNCTION(enFunc));
+
+ if(Enable == enNewState)
+ {
+ if(0ul == (pstcI2sReg->CTRL & (1ul << enFunc)))
+ {
+ pstcI2sReg->CTRL |= (1ul << enFunc);
+ }
+ }
+ else
+ {
+ if(0ul != (pstcI2sReg->CTRL & (1ul << enFunc)))
+ {
+ pstcI2sReg->CTRL &= ~(1ul << (uint8_t)enFunc);
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get I2S status bit
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \param [in] enStd I2S status bit
+ ** \arg Refer @ref en_i2s_std_t
+ **
+ ** \retval Set flag is set
+ ** \retval Reset flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t I2S_GetStatus(M4_I2S_TypeDef* pstcI2sReg, en_i2s_std_t enStd)
+{
+ en_flag_status_t enRet = Reset;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+ DDL_ASSERT(IS_VALID_I2S_STATUS(enStd));
+
+ if (0ul != ((uint32_t)(pstcI2sReg->SR & (1ul << (uint8_t)enStd))))
+ {
+ enRet = Set;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear I2S error flag
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \param [in] enErrFlag I2S Error flag
+ ** \arg Refer @ref en_i2s_err_flag_t
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void I2S_ClrErrFlag(M4_I2S_TypeDef* pstcI2sReg, en_i2s_err_flag_t enErrFlag)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+ DDL_ASSERT(IS_VALID_I2S_ERR_FLAG(enErrFlag));
+
+ pstcI2sReg->ER |= (1ul << (uint8_t)enErrFlag);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get I2S error flag
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \param [in] enErrFlag I2S Error flag
+ ** \arg Refer @ref en_i2s_err_flag_t
+ **
+ ** \retval Set flag is set
+ ** \retval Reset flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t I2S_GetErrFlag(M4_I2S_TypeDef* pstcI2sReg,
+ en_i2s_err_flag_t enErrFlag)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+ DDL_ASSERT(IS_VALID_I2S_ERR_FLAG(enErrFlag));
+
+ return (en_flag_status_t)((uint32_t)(pstcI2sReg->ER | (1ul << (uint8_t)enErrFlag)));
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write data to I2s data send register
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \param [in] u32Data Data to be send
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void I2S_SendData(M4_I2S_TypeDef* pstcI2sReg, uint32_t u32Data)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+
+ pstcI2sReg->TXBUF = u32Data;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read data from I2s data receive register
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ **
+ ** \retval uint32_t The data read out
+ **
+ ******************************************************************************/
+uint32_t I2S_RevData(const M4_I2S_TypeDef* pstcI2sReg)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+
+ return pstcI2sReg->RXBUF;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize I2S module
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \arg M4_I2S1 I2s channel 1
+ ** \arg M4_I2S2 I2s channel 2
+ ** \arg M4_I2S3 I2s channel 3
+ ** \arg M4_I2S4 I2s channel 4
+ ** \param [in] pstcI2sCfg Pointer to I2S configuration structure
+ **
+ ** \retval Ok Initialize successfully done
+ **
+ ******************************************************************************/
+en_result_t I2s_Init(M4_I2S_TypeDef* pstcI2sReg, const stc_i2s_config_t* pstcI2sCfg)
+{
+ uint32_t i2sclk = 0ul, tmp=0ul;
+ uint8_t u8ChanelDataBit,u8ChanMul;
+ uint16_t i2sdiv, i2sodd;
+ stc_i2s_cfgr_field_t stcCFGR_Tmp = {0};
+ stc_i2s_ctrl_field_t stcCTRL_Tmp = {0};
+ en_result_t enRes = Ok;
+ uint32_t u32AdrTmp = 0ul;
+
+ if((NULL == pstcI2sReg)||(NULL == pstcI2sCfg))
+ {
+ enRes = ErrorInvalidParameter;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+ DDL_ASSERT(IS_VALID_I2S_MODE(pstcI2sCfg->enMode));
+ DDL_ASSERT(IS_VALID_I2S_DUPLEX_MODE(pstcI2sCfg->enFullDuplexMode));
+ DDL_ASSERT(IS_VALID_I2S_STANDARD(pstcI2sCfg->enStandrad));
+ DDL_ASSERT(IS_VALID_I2S_DATA_LEN(pstcI2sCfg->enDataBits));
+ DDL_ASSERT(IS_VALID_I2S_CHANNEL_LEN(pstcI2sCfg->enChanelLen));
+ DDL_ASSERT(IS_VALID_I2S_MCKOUT(pstcI2sCfg->enMcoOutEn));
+ DDL_ASSERT(IS_VALID_I2S_EXCK(pstcI2sCfg->enExckEn));
+ DDL_ASSERT(IS_I2S_AUDIO_FREQ(pstcI2sCfg->u32AudioFreq));
+
+ /* Set config register to default value*/
+ pstcI2sReg->CTRL = I2S_REG_CTRL_RESET_VALUE;
+ /* Clear status register*/
+ pstcI2sReg->ER_f.TXERR = 1ul;
+ pstcI2sReg->ER_f.RXERR = 1ul;
+
+ //*(uint32_t*)&stcCTRL_Tmp = pstcI2sReg->CTRL;
+ u32AdrTmp = (uint32_t)&stcCTRL_Tmp;
+ *(uint32_t*)u32AdrTmp = pstcI2sReg->CTRL;
+
+ /* ---- config I2s clock source---- */
+ if(Enable == pstcI2sCfg->enExckEn)
+ {
+ /* Set external clock as I2S clock source */
+ stcCTRL_Tmp.CLKSEL = 1ul;
+ stcCTRL_Tmp.I2SPLLSEL = 0ul;
+ /* Set the I2S clock to the external clock value */
+ i2sclk = I2S_EXTERNAL_CLOCK_VAL;
+ }
+ else
+ {
+ /* Set internal clock as I2S clock source */
+ stcCTRL_Tmp.CLKSEL = 0ul;
+ stcCTRL_Tmp.I2SPLLSEL = 1ul;
+ /* Get i2s clock internal frequency */
+ i2sclk = pstcI2sCfg->u32I2sInterClkFreq;
+ }
+ /* config audio sampple rate */
+ if(I2s_ChLen_16Bit == pstcI2sCfg->enChanelLen)
+ {
+ u8ChanelDataBit = 16u;
+ u8ChanMul = 8u;
+ }
+ else
+ {
+ u8ChanelDataBit = 32u;
+ u8ChanMul = 4u;
+ }
+
+ /*config I2S clock*/
+ if(true == pstcI2sCfg->enMcoOutEn)
+ {
+ /* MCLK output is enabled */
+ tmp = i2sclk/(pstcI2sCfg->u32AudioFreq * u8ChanelDataBit * 2ul * u8ChanMul);
+ }
+ else
+ {
+ /* MCLK output is disabled */
+ tmp = i2sclk/(pstcI2sCfg->u32AudioFreq * u8ChanelDataBit * 2ul);
+ }
+ i2sodd = (uint16_t)(tmp & 0x0001ul);
+ i2sdiv = (uint16_t)((tmp - (uint32_t)i2sodd) / 2ul);
+
+ /* Test if the divider is 1 or 0 or greater than 0xFF */
+ if ((i2sdiv < 2u) || (i2sdiv > 0xFFu))
+ {
+ /* Set the default values */
+ i2sdiv = 2u;
+ i2sodd = 0u;
+ }
+
+ /* Write I2SPR register */
+ pstcI2sReg->PR_f.I2SDIV = (uint8_t)i2sdiv;
+
+ /* Config and write I2S_CFGR */
+ stcCFGR_Tmp.CHLEN = pstcI2sCfg->enChanelLen;
+ stcCFGR_Tmp.DATLEN = pstcI2sCfg->enDataBits;
+ stcCFGR_Tmp.I2SSTD = pstcI2sCfg->enStandrad;
+ stcCFGR_Tmp.PCMSYNC = PCM_SYNC_FRAME;
+ pstcI2sReg->CFGR_f = stcCFGR_Tmp;
+
+ /* Config CTRL register */
+ stcCTRL_Tmp.WMS = pstcI2sCfg->enMode;
+ stcCTRL_Tmp.DUPLEX = pstcI2sCfg->enFullDuplexMode;
+ if(I2sMaster == pstcI2sCfg->enMode)
+ {
+ stcCTRL_Tmp.CKOE = 1u;
+ stcCTRL_Tmp.LRCKOE = 1u;
+ }
+ stcCTRL_Tmp.SDOE = 1u;
+ stcCTRL_Tmp.MCKOE = pstcI2sCfg->enMcoOutEn;
+ stcCTRL_Tmp.ODD = (uint8_t)i2sodd;
+ stcCTRL_Tmp.RXBIRQWL = RXBUF_IRQ_WL;
+ stcCTRL_Tmp.TXBIRQWL = TXBUF_IRQ_WL;
+ //pstcI2sReg->CTRL = *(uint32_t*)&stcCTRL_Tmp;
+ u32AdrTmp = (uint32_t)&stcCTRL_Tmp;
+ pstcI2sReg->CTRL = *(uint32_t*)u32AdrTmp;
+ }
+ return enRes;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initialize I2S module
+ **
+ ** \param [in] pstcI2sReg Pointer to I2S register
+ ** \arg M4_I2S1 I2s channel 1
+ ** \arg M4_I2S2 I2s channel 2
+ ** \arg M4_I2S3 I2s channel 3
+ ** \arg M4_I2S4 I2s channel 4
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t I2s_DeInit(M4_I2S_TypeDef* pstcI2sReg)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
+
+ /* Set config register to default value*/
+ pstcI2sReg->CTRL = I2S_REG_CTRL_RESET_VALUE;
+ /* Clear status register*/
+ pstcI2sReg->ER_f.TXERR = 1u;
+ pstcI2sReg->ER_f.RXERR = 1u;
+
+ return Ok;
+}
+
+//@} // I2sGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_icg.c b/lib/hc32f460/driver/src/hc32f460_icg.c new file mode 100644 index 00000000..fc8bd8ad --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_icg.c @@ -0,0 +1,79 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_icg.c
+ **
+ ** A detailed description is available at
+ ** @link IcgGroup Initialize Configure description @endlink
+ **
+ ** - 2018-10-15 CDT First version for Device Driver Library of ICG.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_icg.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup IcgGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
+const uint32_t u32ICG[] __attribute__((section(".icg_sec"))) =
+#elif defined (__CC_ARM)
+const uint32_t u32ICG[] __attribute__((at(0x400))) =
+#elif defined (__ICCARM__)
+__root const uint32_t u32ICG[] @ 0x400 =
+#else
+#error "unsupported compiler!!"
+#endif
+{
+ /* ICG 0~ 3 */
+ ICG0_REGISTER_CONSTANT,
+ ICG1_REGISTER_CONSTANT,
+ ICG2_REGISTER_CONSTANT,
+ ICG3_REGISTER_CONSTANT,
+ /* ICG 4~ 7 */
+ ICG4_REGISTER_CONSTANT,
+ ICG5_REGISTER_CONSTANT,
+ ICG6_REGISTER_CONSTANT,
+ ICG7_REGISTER_CONSTANT,
+};
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+//@} // IcgGroup
+
+/******************************************************************************
+ * EOF (not truncated)
+ *****************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_interrupts.c b/lib/hc32f460/driver/src/hc32f460_interrupts.c new file mode 100644 index 00000000..fb6174a3 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_interrupts.c @@ -0,0 +1,3779 @@ +/******************************************************************************
+ * 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
+ */
+/*****************************************************************************/
+/** \file hc32f460_interrupts.c
+ **
+ ** A detailed description is available at
+ ** @link InterruptGroup Interrupt description @endlink
+ **
+ ** - 2018-10-12 CDT First version for Device Driver Library of interrupt.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_interrupts.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup InterruptGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*! Parameter validity check for null pointer. */
+#define IS_NULL_POINT(x) (NULL != (x))
+
+/*! Max IRQ Handler. */
+#define IRQ_NUM_MAX (128u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+func_ptr_t IrqHandler[IRQ_NUM_MAX] = {NULL};
+
+/**
+ *******************************************************************************
+ ** \brief IRQ Registration
+ **
+ ** param [in] pstcIrqRegiConf, IRQ registration
+ ** configure structure
+ **
+ ** retval Ok, IRQ register successfully.
+ ** ErrorInvalidParameter, IRQ No. and
+ ** Vector No. are not match.
+ ** ErrorUninitialized, Make sure the
+ ** Interrupt select register (INTSEL) is
+ ** default value (0x1FFu) before setting.
+ **
+ *****************************************************************************/
+en_result_t enIrqRegistration(const stc_irq_regi_conf_t *pstcIrqRegiConf)
+{
+ // todo, assert ...
+ stc_intc_sel_field_t *stcIntSel;
+ en_result_t enRet = Ok;
+
+ //DDL_ASSERT(NULL != pstcIrqRegiConf->pfnCallback);
+ DDL_ASSERT(IS_NULL_POINT(pstcIrqRegiConf->pfnCallback));
+
+ /* IRQ032~127 whether out of range */
+ if (((((pstcIrqRegiConf->enIntSrc/32)*6 + 32) > pstcIrqRegiConf->enIRQn) || \
+ (((pstcIrqRegiConf->enIntSrc/32)*6 + 37) < pstcIrqRegiConf->enIRQn)) && \
+ (pstcIrqRegiConf->enIRQn >= 32))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ stcIntSel = (stc_intc_sel_field_t *)((uint32_t)(&M4_INTC->SEL0) + \
+ (4u * pstcIrqRegiConf->enIRQn));
+ if (0x1FFu == stcIntSel->INTSEL)
+ {
+ stcIntSel->INTSEL = pstcIrqRegiConf->enIntSrc;
+ IrqHandler[pstcIrqRegiConf->enIRQn] = pstcIrqRegiConf->pfnCallback;
+ }
+ else
+ {
+ enRet = ErrorUninitialized;
+ }
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief IRQ Resign
+ **
+ ** param [in] enIRQn, IRQ enumunation (Int000_IRQn ~
+ ** Int127_IRQn
+ **
+ ** retval Ok, IRQ resign sucessfully.
+ ** ErrorInvalidParameter, IRQ No. is out
+ ** of range
+ **
+ *****************************************************************************/
+en_result_t enIrqResign(IRQn_Type enIRQn)
+{
+ stc_intc_sel_field_t *stcIntSel;
+ en_result_t enRet = Ok;
+
+ if ((enIRQn < Int000_IRQn) || (enIRQn > Int127_IRQn))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ stcIntSel = (stc_intc_sel_field_t *)((uint32_t)(&M4_INTC->SEL0) + (4ul * enIRQn));
+ stcIntSel->INTSEL = 0x1FFu;
+ IrqHandler[enIRQn] = NULL;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Share IRQ handler enable
+ **
+ ** param [in] enIntSrc, interrupt souce, This parameter
+ ** can be any value of @ref en_int_src_t
+ **
+ ** retval Ok
+ **
+ ******************************************************************************/
+en_result_t enShareIrqEnable(en_int_src_t enIntSrc)
+{
+ uint32_t *VSSELx;
+
+ //todo assert
+
+ VSSELx = (uint32_t *)(((uint32_t)&M4_INTC->VSSEL128) + (4u * (enIntSrc/32u)));
+ *VSSELx |= (uint32_t)(1ul << (enIntSrc & 0x1Fu));
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Share IRQ handler disable
+ **
+ ** param [in] enIntSrc, interrupt souce, This parameter
+ ** can be any value of @ref en_int_src_t
+ **
+ ** retval Ok
+ **
+ ******************************************************************************/
+en_result_t enShareIrqDisable(en_int_src_t enIntSrc)
+{
+ uint32_t *VSSELx;
+
+ //todo assert
+
+ VSSELx = (uint32_t *)(((uint32_t)&M4_INTC->VSSEL128) + (4u * (enIntSrc/32u)));
+ *VSSELx &= ~(uint32_t)(1ul << (enIntSrc & 0x1Fu));
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable stop mode wakeup source
+ **
+ ** param [in] u32WakeupSrc, This parameter can be any
+ ** composed value of @ref en_int_wkup_src_t
+ **
+ ** retval Ok, corresponding wakeup source be enabled
+ ** ErrorInvalidParameter, parameter with
+ ** non-definition bits
+ **
+ ******************************************************************************/
+en_result_t enIntWakeupEnable(uint32_t u32WakeupSrc)
+{
+ en_result_t enRet = Ok;
+ if (0ul != (u32WakeupSrc & 0xFD000000ul))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ M4_INTC->WUPEN |= u32WakeupSrc;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Disable stop mode wakeup source
+ **
+ ** param [in] u32WakeupSrc, This parameter can be any
+ ** composed value of @ref en_int_wkup_src_t
+ **
+ ** retval Ok, corresponding wakeup source be disabled
+ ** ErrorInvalidParameter, parameter with
+ ** non-definition bits
+ **
+ ******************************************************************************/
+en_result_t enIntWakeupDisable(uint32_t u32WakeupSrc)
+{
+ en_result_t enRet = Ok;
+ if (0ul != (u32WakeupSrc & 0xFD000000u))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ M4_INTC->WUPEN &= ~u32WakeupSrc;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Event enable
+ **
+ ** param [in] u32Event, This parameter can be
+ ** any composed value of @ref en_evt_t
+ **
+ ** retval Ok, corresponding event Ch. be enabled
+ **
+ ******************************************************************************/
+en_result_t enEventEnable(uint32_t u32Event)
+{
+ M4_INTC->EVTER |= u32Event;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Event enable
+ **
+ ** param [in] u32Event, This parameter can be
+ ** any composed value of @ref en_evt_t
+ **
+ ** retval Ok, corresponding event Ch. be disabled
+ **
+ ******************************************************************************/
+en_result_t enEventDisable(uint32_t u32Event)
+{
+ M4_INTC->EVTER &= ~u32Event;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Interrupt enable
+ **
+ * param [in] u32Int, This parameter can be any composed
+ * value of @ref en_int_t
+ **
+ ** retval Ok, corresponding interrupt vector be enabled
+ **
+ ******************************************************************************/
+en_result_t enIntEnable(uint32_t u32Int)
+{
+ M4_INTC->IER |= u32Int;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Interrupt disable
+ **
+ * param [in] u32Int, This parameter can be any composed
+ * value of @ref en_int_t
+ **
+ ** retval Ok, corresponding interrupt vector be disabled
+ **
+ ******************************************************************************/
+en_result_t enIntDisable(uint32_t u32Int)
+{
+ M4_INTC->IER &= ~u32Int;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief NMI IRQ handler
+ **
+ ******************************************************************************/
+void NMI_Handler(void)
+{
+ NMI_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Hard Fault IRQ handler
+ **
+ ******************************************************************************/
+void HardFault_Handler(void)
+{
+ HardFault_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief MPU Fault IRQ handler
+ **
+ ******************************************************************************/
+void MemManage_Handler(void)
+{
+ MemManage_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Bus Fault IRQ handler
+ **
+ ******************************************************************************/
+void BusFault_Handler(void)
+{
+ BusFault_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Usage Fault IRQ handler
+ **
+ ******************************************************************************/
+void UsageFault_Handler(void)
+{
+ UsageFault_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief SVCall IRQ handler
+ **
+ ******************************************************************************/
+void SVC_Handler(void)
+{
+ SVC_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief DebugMon IRQ handler
+ **
+ ******************************************************************************/
+void DebugMon_Handler(void)
+{
+ DebugMon_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief PendSV IRQ handler
+ **
+ ******************************************************************************/
+void PendSV_Handler(void)
+{
+ PendSV_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Systick IRQ handler
+ **
+ ******************************************************************************/
+void SysTick_Handler(void)
+{
+ SysTick_IrqHandler();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.000 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ000_Handler(void)
+{
+ if (NULL != IrqHandler[Int000_IRQn])
+ {
+ IrqHandler[Int000_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.001 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ001_Handler(void)
+{
+ if (NULL != IrqHandler[Int001_IRQn])
+ {
+ IrqHandler[Int001_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.002 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ002_Handler(void)
+{
+ if (NULL != IrqHandler[Int002_IRQn])
+ {
+ IrqHandler[Int002_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.003 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ003_Handler(void)
+{
+ if (NULL != IrqHandler[Int003_IRQn])
+ {
+ IrqHandler[Int003_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.004 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ004_Handler(void)
+{
+ if (NULL != IrqHandler[Int004_IRQn])
+ {
+ IrqHandler[Int004_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.005 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ005_Handler(void)
+{
+ if (NULL != IrqHandler[Int005_IRQn])
+ {
+ IrqHandler[Int005_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.006 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ006_Handler(void)
+{
+ if (NULL != IrqHandler[Int006_IRQn])
+ {
+ IrqHandler[Int006_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.007 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ007_Handler(void)
+{
+ if (NULL != IrqHandler[Int007_IRQn])
+ {
+ IrqHandler[Int007_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.008 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ008_Handler(void)
+{
+ if (NULL != IrqHandler[Int008_IRQn])
+ {
+ IrqHandler[Int008_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.009 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ009_Handler(void)
+{
+ if (NULL != IrqHandler[Int009_IRQn])
+ {
+ IrqHandler[Int009_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.010 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ010_Handler(void)
+{
+ if (NULL != IrqHandler[Int010_IRQn])
+ {
+ IrqHandler[Int010_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.011 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ011_Handler(void)
+{
+ if (NULL != IrqHandler[Int011_IRQn])
+ {
+ IrqHandler[Int011_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.012 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ012_Handler(void)
+{
+ if (NULL != IrqHandler[Int012_IRQn])
+ {
+ IrqHandler[Int012_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.013 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ013_Handler(void)
+{
+ if (NULL != IrqHandler[Int013_IRQn])
+ {
+ IrqHandler[Int013_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.014 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ014_Handler(void)
+{
+ if (NULL != IrqHandler[Int014_IRQn])
+ {
+ IrqHandler[Int014_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.015 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ015_Handler(void)
+{
+ if (NULL != IrqHandler[Int015_IRQn])
+ {
+ IrqHandler[Int015_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.016 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ016_Handler(void)
+{
+ if (NULL != IrqHandler[Int016_IRQn])
+ {
+ IrqHandler[Int016_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.017 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ017_Handler(void)
+{
+ if (NULL != IrqHandler[Int017_IRQn])
+ {
+ IrqHandler[Int017_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.018 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ018_Handler(void)
+{
+ if (NULL != IrqHandler[Int018_IRQn])
+ {
+ IrqHandler[Int018_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.019 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ019_Handler(void)
+{
+ if (NULL != IrqHandler[Int019_IRQn])
+ {
+ IrqHandler[Int019_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.020 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ020_Handler(void)
+{
+ if (NULL != IrqHandler[Int020_IRQn])
+ {
+ IrqHandler[Int020_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.021 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ021_Handler(void)
+{
+ if (NULL != IrqHandler[Int021_IRQn])
+ {
+ IrqHandler[Int021_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.022 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ022_Handler(void)
+{
+ if (NULL != IrqHandler[Int022_IRQn])
+ {
+ IrqHandler[Int022_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.023 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ023_Handler(void)
+{
+ if (NULL != IrqHandler[Int023_IRQn])
+ {
+ IrqHandler[Int023_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.024 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ024_Handler(void)
+{
+ if (NULL != IrqHandler[Int024_IRQn])
+ {
+ IrqHandler[Int024_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.025 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ025_Handler(void)
+{
+ if (NULL != IrqHandler[Int025_IRQn])
+ {
+ IrqHandler[Int025_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.026 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ026_Handler(void)
+{
+ if (NULL != IrqHandler[Int026_IRQn])
+ {
+ IrqHandler[Int026_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.027 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ027_Handler(void)
+{
+ if (NULL != IrqHandler[Int027_IRQn])
+ {
+ IrqHandler[Int027_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.028 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ028_Handler(void)
+{
+ if (NULL != IrqHandler[Int028_IRQn])
+ {
+ IrqHandler[Int028_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.029 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ029_Handler(void)
+{
+ if (NULL != IrqHandler[Int029_IRQn])
+ {
+ IrqHandler[Int029_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.030 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ030_Handler(void)
+{
+ if (NULL != IrqHandler[Int030_IRQn])
+ {
+ IrqHandler[Int030_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.031 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ031_Handler(void)
+{
+ if (NULL != IrqHandler[Int031_IRQn])
+ {
+ IrqHandler[Int031_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.032 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ032_Handler(void)
+{
+ if (NULL != IrqHandler[Int032_IRQn])
+ {
+ IrqHandler[Int032_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.033 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ033_Handler(void)
+{
+ if (NULL != IrqHandler[Int033_IRQn])
+ {
+ IrqHandler[Int033_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.034 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ034_Handler(void)
+{
+ if (NULL != IrqHandler[Int034_IRQn])
+ {
+ IrqHandler[Int034_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.035 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ035_Handler(void)
+{
+ if (NULL != IrqHandler[Int035_IRQn])
+ {
+ IrqHandler[Int035_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.036 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ036_Handler(void)
+{
+ if (NULL != IrqHandler[Int036_IRQn])
+ {
+ IrqHandler[Int036_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.037 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ037_Handler(void)
+{
+ if (NULL != IrqHandler[Int037_IRQn])
+ {
+ IrqHandler[Int037_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.038 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ038_Handler(void)
+{
+ if (NULL != IrqHandler[Int038_IRQn])
+ {
+ IrqHandler[Int038_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.039 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ039_Handler(void)
+{
+ if (NULL != IrqHandler[Int039_IRQn])
+ {
+ IrqHandler[Int039_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.040 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ040_Handler(void)
+{
+ if (NULL != IrqHandler[Int040_IRQn])
+ {
+ IrqHandler[Int040_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.041 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ041_Handler(void)
+{
+ if (NULL != IrqHandler[Int041_IRQn])
+ {
+ IrqHandler[Int041_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.042 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ042_Handler(void)
+{
+ if (NULL != IrqHandler[Int042_IRQn])
+ {
+ IrqHandler[Int042_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.043 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ043_Handler(void)
+{
+ if (NULL != IrqHandler[Int043_IRQn])
+ {
+ IrqHandler[Int043_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.044 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ044_Handler(void)
+{
+ if (NULL != IrqHandler[Int044_IRQn])
+ {
+ IrqHandler[Int044_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.045 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ045_Handler(void)
+{
+ if (NULL != IrqHandler[Int045_IRQn])
+ {
+ IrqHandler[Int045_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.046 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ046_Handler(void)
+{
+ if (NULL != IrqHandler[Int046_IRQn])
+ {
+ IrqHandler[Int046_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.047 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ047_Handler(void)
+{
+ if (NULL != IrqHandler[Int047_IRQn])
+ {
+ IrqHandler[Int047_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.048 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ048_Handler(void)
+{
+ if (NULL != IrqHandler[Int048_IRQn])
+ {
+ IrqHandler[Int048_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.049 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ049_Handler(void)
+{
+ if (NULL != IrqHandler[Int049_IRQn])
+ {
+ IrqHandler[Int049_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.050 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ050_Handler(void)
+{
+ if (NULL != IrqHandler[Int050_IRQn])
+ {
+ IrqHandler[Int050_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.051 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ051_Handler(void)
+{
+ if (NULL != IrqHandler[Int051_IRQn])
+ {
+ IrqHandler[Int051_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.052 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ052_Handler(void)
+{
+ if (NULL != IrqHandler[Int052_IRQn])
+ {
+ IrqHandler[Int052_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.053 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ053_Handler(void)
+{
+ if (NULL != IrqHandler[Int053_IRQn])
+ {
+ IrqHandler[Int053_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.054 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ054_Handler(void)
+{
+ if (NULL != IrqHandler[Int054_IRQn])
+ {
+ IrqHandler[Int054_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.055 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ055_Handler(void)
+{
+ if (NULL != IrqHandler[Int055_IRQn])
+ {
+ IrqHandler[Int055_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.056 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ056_Handler(void)
+{
+ if (NULL != IrqHandler[Int056_IRQn])
+ {
+ IrqHandler[Int056_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.057 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ057_Handler(void)
+{
+ if (NULL != IrqHandler[Int057_IRQn])
+ {
+ IrqHandler[Int057_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.058 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ058_Handler(void)
+{
+ if (NULL != IrqHandler[Int058_IRQn])
+ {
+ IrqHandler[Int058_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.059 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ059_Handler(void)
+{
+ if (NULL != IrqHandler[Int059_IRQn])
+ {
+ IrqHandler[Int059_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.060 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ060_Handler(void)
+{
+ if (NULL != IrqHandler[Int060_IRQn])
+ {
+ IrqHandler[Int060_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.061 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ061_Handler(void)
+{
+ if (NULL != IrqHandler[Int061_IRQn])
+ {
+ IrqHandler[Int061_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.062 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ062_Handler(void)
+{
+ if (NULL != IrqHandler[Int062_IRQn])
+ {
+ IrqHandler[Int062_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.063 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ063_Handler(void)
+{
+ if (NULL != IrqHandler[Int063_IRQn])
+ {
+ IrqHandler[Int063_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.064 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ064_Handler(void)
+{
+ if (NULL != IrqHandler[Int064_IRQn])
+ {
+ IrqHandler[Int064_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.065 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ065_Handler(void)
+{
+ if (NULL != IrqHandler[Int065_IRQn])
+ {
+ IrqHandler[Int065_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.066 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ066_Handler(void)
+{
+ if (NULL != IrqHandler[Int066_IRQn])
+ {
+ IrqHandler[Int066_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.067 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ067_Handler(void)
+{
+ if (NULL != IrqHandler[Int067_IRQn])
+ {
+ IrqHandler[Int067_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.068 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ068_Handler(void)
+{
+ if (NULL != IrqHandler[Int068_IRQn])
+ {
+ IrqHandler[Int068_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.069 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ069_Handler(void)
+{
+ if (NULL != IrqHandler[Int069_IRQn])
+ {
+ IrqHandler[Int069_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.070 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ070_Handler(void)
+{
+ if (NULL != IrqHandler[Int070_IRQn])
+ {
+ IrqHandler[Int070_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.071 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ071_Handler(void)
+{
+ if (NULL != IrqHandler[Int071_IRQn])
+ {
+ IrqHandler[Int071_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.072 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ072_Handler(void)
+{
+ if (NULL != IrqHandler[Int072_IRQn])
+ {
+ IrqHandler[Int072_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.073 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ073_Handler(void)
+{
+ if (NULL != IrqHandler[Int073_IRQn])
+ {
+ IrqHandler[Int073_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.074 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ074_Handler(void)
+{
+ if (NULL != IrqHandler[Int074_IRQn])
+ {
+ IrqHandler[Int074_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.075 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ075_Handler(void)
+{
+ if (NULL != IrqHandler[Int075_IRQn])
+ {
+ IrqHandler[Int075_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.076 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ076_Handler(void)
+{
+ if (NULL != IrqHandler[Int076_IRQn])
+ {
+ IrqHandler[Int076_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.077 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ077_Handler(void)
+{
+ if (NULL != IrqHandler[Int077_IRQn])
+ {
+ IrqHandler[Int077_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.078 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ078_Handler(void)
+{
+ if (NULL != IrqHandler[Int078_IRQn])
+ {
+ IrqHandler[Int078_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.079 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ079_Handler(void)
+{
+ if (NULL != IrqHandler[Int079_IRQn])
+ {
+ IrqHandler[Int079_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.080 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ080_Handler(void)
+{
+ if (NULL != IrqHandler[Int080_IRQn])
+ {
+ IrqHandler[Int080_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.081 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ081_Handler(void)
+{
+ if (NULL != IrqHandler[Int081_IRQn])
+ {
+ IrqHandler[Int081_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.082 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ082_Handler(void)
+{
+ if (NULL != IrqHandler[Int082_IRQn])
+ {
+ IrqHandler[Int082_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.083 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ083_Handler(void)
+{
+ if (NULL != IrqHandler[Int083_IRQn])
+ {
+ IrqHandler[Int083_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.084 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ084_Handler(void)
+{
+ if (NULL != IrqHandler[Int084_IRQn])
+ {
+ IrqHandler[Int084_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.085 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ085_Handler(void)
+{
+ if (NULL != IrqHandler[Int085_IRQn])
+ {
+ IrqHandler[Int085_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.086 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ086_Handler(void)
+{
+ if (NULL != IrqHandler[Int086_IRQn])
+ {
+ IrqHandler[Int086_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.087 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ087_Handler(void)
+{
+ if (NULL != IrqHandler[Int087_IRQn])
+ {
+ IrqHandler[Int087_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.088 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ088_Handler(void)
+{
+ if (NULL != IrqHandler[Int088_IRQn])
+ {
+ IrqHandler[Int088_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.089 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ089_Handler(void)
+{
+ if (NULL != IrqHandler[Int089_IRQn])
+ {
+ IrqHandler[Int089_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.090 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ090_Handler(void)
+{
+ if (NULL != IrqHandler[Int090_IRQn])
+ {
+ IrqHandler[Int090_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.091 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ091_Handler(void)
+{
+ if (NULL != IrqHandler[Int091_IRQn])
+ {
+ IrqHandler[Int091_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.092 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ092_Handler(void)
+{
+ if (NULL != IrqHandler[Int092_IRQn])
+ {
+ IrqHandler[Int092_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.093 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ093_Handler(void)
+{
+ if (NULL != IrqHandler[Int093_IRQn])
+ {
+ IrqHandler[Int093_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.094 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ094_Handler(void)
+{
+ if (NULL != IrqHandler[Int094_IRQn])
+ {
+ IrqHandler[Int094_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.095 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ095_Handler(void)
+{
+ if (NULL != IrqHandler[Int095_IRQn])
+ {
+ IrqHandler[Int095_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.096 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ096_Handler(void)
+{
+ if (NULL != IrqHandler[Int096_IRQn])
+ {
+ IrqHandler[Int096_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.097 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ097_Handler(void)
+{
+ if (NULL != IrqHandler[Int097_IRQn])
+ {
+ IrqHandler[Int097_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.098 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ098_Handler(void)
+{
+ if (NULL != IrqHandler[Int098_IRQn])
+ {
+ IrqHandler[Int098_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.099 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ099_Handler(void)
+{
+ if (NULL != IrqHandler[Int099_IRQn])
+ {
+ IrqHandler[Int099_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.100 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ100_Handler(void)
+{
+ if (NULL != IrqHandler[Int100_IRQn])
+ {
+ IrqHandler[Int100_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.101 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ101_Handler(void)
+{
+ if (NULL != IrqHandler[Int101_IRQn])
+ {
+ IrqHandler[Int101_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.102 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ102_Handler(void)
+{
+ if (NULL != IrqHandler[Int102_IRQn])
+ {
+ IrqHandler[Int102_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.103 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ103_Handler(void)
+{
+ if (NULL != IrqHandler[Int103_IRQn])
+ {
+ IrqHandler[Int103_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.104 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ104_Handler(void)
+{
+ if (NULL != IrqHandler[Int104_IRQn])
+ {
+ IrqHandler[Int104_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.105 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ105_Handler(void)
+{
+ if (NULL != IrqHandler[Int105_IRQn])
+ {
+ IrqHandler[Int105_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.106 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ106_Handler(void)
+{
+ if (NULL != IrqHandler[Int106_IRQn])
+ {
+ IrqHandler[Int106_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.107 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ107_Handler(void)
+{
+ if (NULL != IrqHandler[Int107_IRQn])
+ {
+ IrqHandler[Int107_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.108 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ108_Handler(void)
+{
+ if (NULL != IrqHandler[Int108_IRQn])
+ {
+ IrqHandler[Int108_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.109 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ109_Handler(void)
+{
+ if (NULL != IrqHandler[Int109_IRQn])
+ {
+ IrqHandler[Int109_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.110 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ110_Handler(void)
+{
+ if (NULL != IrqHandler[Int110_IRQn])
+ {
+ IrqHandler[Int110_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.111 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ111_Handler(void)
+{
+ if (NULL != IrqHandler[Int111_IRQn])
+ {
+ IrqHandler[Int111_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.112 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ112_Handler(void)
+{
+ if (NULL != IrqHandler[Int112_IRQn])
+ {
+ IrqHandler[Int112_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.113 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ113_Handler(void)
+{
+ if (NULL != IrqHandler[Int113_IRQn])
+ {
+ IrqHandler[Int113_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.114 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ114_Handler(void)
+{
+ if (NULL != IrqHandler[Int114_IRQn])
+ {
+ IrqHandler[Int114_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.115 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ115_Handler(void)
+{
+ if (NULL != IrqHandler[Int115_IRQn])
+ {
+ IrqHandler[Int115_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.116 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ116_Handler(void)
+{
+ if (NULL != IrqHandler[Int116_IRQn])
+ {
+ IrqHandler[Int116_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.117 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ117_Handler(void)
+{
+ if (NULL != IrqHandler[Int117_IRQn])
+ {
+ IrqHandler[Int117_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.118 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ118_Handler(void)
+{
+ if (NULL != IrqHandler[Int118_IRQn])
+ {
+ IrqHandler[Int118_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.119 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ119_Handler(void)
+{
+ if (NULL != IrqHandler[Int119_IRQn])
+ {
+ IrqHandler[Int119_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.120 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ120_Handler(void)
+{
+ if (NULL != IrqHandler[Int120_IRQn])
+ {
+ IrqHandler[Int120_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.121 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ121_Handler(void)
+{
+ if (NULL != IrqHandler[Int121_IRQn])
+ {
+ IrqHandler[Int121_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.122 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ122_Handler(void)
+{
+ if (NULL != IrqHandler[Int122_IRQn])
+ {
+ IrqHandler[Int122_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.123 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ123_Handler(void)
+{
+ if (NULL != IrqHandler[Int123_IRQn])
+ {
+ IrqHandler[Int123_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.124 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ124_Handler(void)
+{
+ if (NULL != IrqHandler[Int124_IRQn])
+ {
+ IrqHandler[Int124_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.125 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ125_Handler(void)
+{
+ if (NULL != IrqHandler[Int125_IRQn])
+ {
+ IrqHandler[Int125_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.126 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ126_Handler(void)
+{
+ if (NULL != IrqHandler[Int126_IRQn])
+ {
+ IrqHandler[Int126_IRQn]();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.127 IRQ handler
+ **
+ ******************************************************************************/
+void IRQ127_Handler(void)
+{
+ if (NULL != IrqHandler[Int127_IRQn])
+ {
+ IrqHandler[Int127_IRQn]();
+ }
+}
+
+#if defined(INTERRUPTS_SHARE_ENABLE)
+/**
+ *******************************************************************************
+ ** \brief Int No.128 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ128_Handler(void)
+{
+ uint32_t VSSEL128 = M4_INTC->VSSEL128;
+
+ /* external interrupt 00 */
+ if ((1ul == bM4_INTC_EIFR_EIFR0) && (VSSEL128 & BIT_MASK_00))
+ {
+ Extint00_IrqHandler();
+ }
+ /* external interrupt 01 */
+ if ((1ul == bM4_INTC_EIFR_EIFR1) && (VSSEL128 & BIT_MASK_01))
+ {
+ Extint01_IrqHandler();
+ }
+ /* external interrupt 02 */
+ if ((1ul == bM4_INTC_EIFR_EIFR2) && (VSSEL128 & BIT_MASK_02))
+ {
+ Extint02_IrqHandler();
+ }
+ /* external interrupt 03 */
+ if ((1ul == bM4_INTC_EIFR_EIFR3) && (VSSEL128 & BIT_MASK_03))
+ {
+ Extint03_IrqHandler();
+ }
+ /* external interrupt 04 */
+ if ((1ul == bM4_INTC_EIFR_EIFR4) && (VSSEL128 & BIT_MASK_04))
+ {
+ Extint04_IrqHandler();
+ }
+ /* external interrupt 05 */
+ if ((1ul == bM4_INTC_EIFR_EIFR5) && (VSSEL128 & BIT_MASK_05))
+ {
+ Extint05_IrqHandler();
+ }
+ /* external interrupt 06 */
+ if ((1ul == bM4_INTC_EIFR_EIFR6) && (VSSEL128 & BIT_MASK_06))
+ {
+ Extint06_IrqHandler();
+ }
+ /* external interrupt 07 */
+ if ((1ul == bM4_INTC_EIFR_EIFR7) && (VSSEL128 & BIT_MASK_07))
+ {
+ Extint07_IrqHandler();
+ }
+ /* external interrupt 08 */
+ if ((1ul == bM4_INTC_EIFR_EIFR8) && (VSSEL128 & BIT_MASK_08))
+ {
+ Extint08_IrqHandler();
+ }
+ /* external interrupt 09 */
+ if ((1ul == bM4_INTC_EIFR_EIFR9) && (VSSEL128 & BIT_MASK_09))
+ {
+ Extint09_IrqHandler();
+ }
+ /* external interrupt 10 */
+ if ((1ul == bM4_INTC_EIFR_EIFR10) && (VSSEL128 & BIT_MASK_10))
+ {
+ Extint10_IrqHandler();
+ }
+ /* external interrupt 11 */
+ if ((1ul == bM4_INTC_EIFR_EIFR11) && (VSSEL128 & BIT_MASK_11))
+ {
+ Extint11_IrqHandler();
+ }
+ /* external interrupt 12 */
+ if ((1ul == bM4_INTC_EIFR_EIFR12) && (VSSEL128 & BIT_MASK_12))
+ {
+ Extint12_IrqHandler();
+ }
+ /* external interrupt 13 */
+ if ((1ul == bM4_INTC_EIFR_EIFR13) && (VSSEL128 & BIT_MASK_13))
+ {
+ Extint13_IrqHandler();
+ }
+ /* external interrupt 14 */
+ if ((1ul == bM4_INTC_EIFR_EIFR14) && (VSSEL128 & BIT_MASK_14))
+ {
+ Extint14_IrqHandler();
+ }
+ /* external interrupt 15 */
+ if ((1ul == bM4_INTC_EIFR_EIFR15) && (VSSEL128 & BIT_MASK_15))
+ {
+ Extint15_IrqHandler();
+ }
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Int No.129 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ129_Handler(void)
+{
+ uint32_t VSSEL129 =M4_INTC->VSSEL129;
+ uint32_t u32Tmp1 = 0ul;
+ uint32_t u32Tmp2 = 0ul;
+
+ if (1ul == bM4_DMA1_CHCTL0_IE)
+ {
+ /* DMA1 ch.0 Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKTC0)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_TC0) && (VSSEL129 & BIT_MASK_00))
+ {
+ Dma1Tc0_IrqHandler();
+ }
+ }
+ /* DMA1 ch.0 Block Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKBTC0)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_BTC0) && (VSSEL129 & BIT_MASK_08))
+ {
+ Dma1Btc0_IrqHandler();
+ }
+ }
+ /* DMA1 ch.0 Transfer/Request Error */
+ u32Tmp1 = M4_DMA1->INTSTAT0 & 0x00010001ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA1->INTMASK0) & 0x00010001ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_16))
+ {
+ Dma1Err0_IrqHandler();
+ }
+ }
+ if (1ul == bM4_DMA1_CHCTL1_IE)
+ {
+ /* DMA1 ch.1 Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKTC1)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_TC1) && (VSSEL129 & BIT_MASK_01))
+ {
+ Dma1Tc1_IrqHandler();
+ }
+ }
+ /* DMA1 ch.1 Block Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKBTC1)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_BTC1) && (VSSEL129 & BIT_MASK_09))
+ {
+ Dma1Btc1_IrqHandler();
+ }
+ }
+ /* DMA1 ch.1 Transfer/Request Error */
+ u32Tmp1 = M4_DMA1->INTSTAT0 & 0x00020002ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA1->INTMASK0) & 0x00020002ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_16))
+ {
+ Dma1Err1_IrqHandler();
+ }
+ }
+ if (1ul == bM4_DMA1_CHCTL2_IE)
+ {
+ /* DMA1 ch.2 Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKTC2)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_TC2) && (VSSEL129 & BIT_MASK_02))
+ {
+ Dma1Tc2_IrqHandler();
+ }
+ }
+ /* DMA1 ch.2 Block Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKBTC2)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_BTC2) && (VSSEL129 & BIT_MASK_10))
+ {
+ Dma1Btc2_IrqHandler();
+ }
+ }
+ /* DMA1 ch.2 Transfer/Request Error */
+ u32Tmp1 = M4_DMA1->INTSTAT0 & 0x00040004ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA1->INTMASK0) & 0x00040004ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_16))
+ {
+ Dma1Err2_IrqHandler();
+ }
+ }
+ if (1ul == bM4_DMA1_CHCTL3_IE)
+ {
+ /* DMA1 ch.3 Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKTC3)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_TC3) && (VSSEL129 & BIT_MASK_03))
+ {
+ Dma1Tc3_IrqHandler();
+ }
+ }
+ /* DMA1 ch.3 Block Tx completed */
+ if (0ul == bM4_DMA1_INTMASK1_MSKBTC3)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_BTC3) && (VSSEL129 & BIT_MASK_11))
+ {
+ Dma1Btc3_IrqHandler();
+ }
+ }
+ /* DMA1 ch.3 Transfer/Request Error */
+ u32Tmp1 = M4_DMA1->INTSTAT0 & 0x00080008ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA1->INTMASK0) & 0x00080008ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_16))
+ {
+ Dma1Err3_IrqHandler();
+ }
+ }
+ if (1ul == bM4_DMA2_CHCTL0_IE)
+ {
+ /* DMA2 ch.0 Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKTC0)
+ {
+ if ((1ul == bM4_DMA2_INTSTAT1_TC0) && (VSSEL129 & BIT_MASK_04))
+ {
+ Dma2Tc0_IrqHandler();
+ }
+ }
+ /* DMA2 ch.0 Block Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKBTC0)
+ {
+ if ((1ul == bM4_DMA2_INTSTAT1_BTC0) && (VSSEL129 & BIT_MASK_12))
+ {
+ Dma2Btc0_IrqHandler();
+ }
+ }
+ /* DMA2 Ch.0 Transfer/Request Error */
+ u32Tmp1 = M4_DMA2->INTSTAT0 & 0x00010001ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA2->INTMASK0) & 0x00010001ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_17))
+ {
+ Dma2Err0_IrqHandler();
+ }
+ }
+ if (1ul == bM4_DMA2_CHCTL1_IE)
+ {
+ /* DMA2 ch.1 Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKTC1)
+ {
+ if ((1ul == bM4_DMA2_INTSTAT1_TC1) && (VSSEL129 & BIT_MASK_05))
+ {
+ Dma2Tc1_IrqHandler();
+ }
+ }
+ /* DMA2 ch.1 Block Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKBTC1)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_BTC1) && (VSSEL129 & BIT_MASK_13))
+ {
+ Dma2Btc1_IrqHandler();
+ }
+ }
+ /* DMA2 Ch.1 Transfer/Request Error */
+ u32Tmp1 = M4_DMA2->INTSTAT0 & 0x00020002ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA2->INTMASK0) & 0x00020002ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_17))
+ {
+ Dma2Err1_IrqHandler();
+ }
+ }
+ if (1ul == bM4_DMA2_CHCTL2_IE)
+ {
+ /* DMA2 ch.2 Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKTC2)
+ {
+ if ((1ul == bM4_DMA2_INTSTAT1_TC2) && (VSSEL129 & BIT_MASK_06))
+ {
+ Dma2Tc2_IrqHandler();
+ }
+ }
+ /* DMA2 ch.2 Block Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKBTC2)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_BTC2) && (VSSEL129 & BIT_MASK_14))
+ {
+ Dma2Btc2_IrqHandler();
+ }
+ }
+ /* DMA2 Ch.2 Transfer/Request Error */
+ u32Tmp1 = M4_DMA2->INTSTAT0 & 0x00040004ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA2->INTMASK0) & 0x00040004ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_17))
+ {
+ Dma2Err2_IrqHandler();
+ }
+ }
+ if (1ul == bM4_DMA2_CHCTL3_IE)
+ {
+ /* DMA2 ch.3 Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKTC3)
+ {
+ if ((1ul == bM4_DMA2_INTSTAT1_TC3) && (VSSEL129 & BIT_MASK_07))
+ {
+ Dma2Tc3_IrqHandler();
+ }
+ }
+ /* DMA2 ch.3 Block Tx completed */
+ if (0ul == bM4_DMA2_INTMASK1_MSKBTC3)
+ {
+ if ((1ul == bM4_DMA1_INTSTAT1_BTC3) && (VSSEL129 & BIT_MASK_15))
+ {
+ Dma2Btc3_IrqHandler();
+ }
+ }
+ /* DMA2 Ch.3 Transfer/Request Error */
+ u32Tmp1 = M4_DMA2->INTSTAT0 & 0x00080008ul;
+ u32Tmp2 = (uint32_t)(~(M4_DMA2->INTMASK0) & 0x00080008ul);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL129 & BIT_MASK_17))
+ {
+ Dma2Err3_IrqHandler();
+ }
+ }
+ /* EFM program/erase Error */
+ if (1ul == bM4_EFM_FITE_PEERRITE)
+ {
+ if ((M4_EFM->FSR & 0x0Fu) && (VSSEL129 & BIT_MASK_18))
+ {
+ EfmPgmEraseErr_IrqHandler();
+ }
+ }
+ /* EFM collision Error */
+ if (1ul == bM4_EFM_FITE_COLERRITE)
+ {
+ if ((1ul == bM4_EFM_FSR_COLERR) && (VSSEL129 & BIT_MASK_19))
+ {
+ EfmColErr_IrqHandler();
+ }
+ }
+ /* EFM operate end */
+ if (1ul == bM4_EFM_FITE_OPTENDITE)
+ {
+ if ((1ul == bM4_EFM_FSR_OPTEND) && (VSSEL129 & BIT_MASK_20))
+ {
+ EfmOpEnd_IrqHandler();
+ }
+ }
+ /* QSPI interrupt */
+ if ((1ul == M4_QSPI->SR_f.RAER) && (VSSEL129 & BIT_MASK_22))
+ {
+ QspiInt_IrqHandler();
+ }
+ /* DCU ch.1 */
+ u32Tmp1 = M4_DCU1->INTSEL;
+ u32Tmp2 = M4_DCU1->FLAG;
+ if ((u32Tmp1 & u32Tmp2 & 0x7Ful) && (VSSEL129 & BIT_MASK_23))
+ {
+ Dcu1_IrqHandler();
+ }
+ /* DCU ch.2 */
+ u32Tmp1 = M4_DCU2->INTSEL;
+ u32Tmp2 = M4_DCU2->FLAG;
+ if ((u32Tmp1 & u32Tmp2 & 0x7Ful) && (VSSEL129 & BIT_MASK_24))
+ {
+ Dcu2_IrqHandler();
+ }
+ /* DCU ch.3 */
+ u32Tmp1 = M4_DCU3->INTSEL;
+ u32Tmp2 = M4_DCU3->FLAG;
+ if ((u32Tmp1 & u32Tmp2 & 0x7Ful) && (VSSEL129 & BIT_MASK_25))
+ {
+ Dcu3_IrqHandler();
+ }
+ /* DCU ch.4 */
+ u32Tmp1 = M4_DCU4->INTSEL;
+ u32Tmp2 = M4_DCU4->FLAG;
+ if ((u32Tmp1 & u32Tmp2 & 0x7Ful) && (VSSEL129 & BIT_MASK_26))
+ {
+ Dcu4_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.130 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ130_Handler(void)
+{
+ uint32_t VSSEL130 = M4_INTC->VSSEL130;
+ /* Timer0 Ch. 1 A compare match */
+ if (1ul == bM4_TMR01_BCONR_INTENA)
+ {
+ if ((1ul == bM4_TMR01_STFLR_CMAF) && (VSSEL130 & BIT_MASK_00))
+ {
+ Timer01GCMA_IrqHandler();
+ }
+ }
+ /* Timer0 Ch. 1 B compare match */
+ if (1ul == bM4_TMR01_BCONR_INTENB)
+ {
+ if ((1ul == bM4_TMR01_STFLR_CMBF) && (VSSEL130 & BIT_MASK_01))
+ {
+ Timer01GCMB_IrqHandler();
+ }
+ }
+ /* Timer0 Ch. 2 A compare match */
+ if (1ul == bM4_TMR02_BCONR_INTENA)
+ {
+ if ((1ul == bM4_TMR02_STFLR_CMAF) && (VSSEL130 & BIT_MASK_02))
+ {
+ Timer02GCMA_IrqHandler();
+ }
+ }
+ /* Timer0 Ch. 2 B compare match */
+ if (1ul == bM4_TMR02_BCONR_INTENB)
+ {
+ if ((1ul == bM4_TMR02_STFLR_CMBF) && (VSSEL130 & BIT_MASK_03))
+ {
+ Timer02GCMB_IrqHandler();
+ }
+ }
+ /* Main-OSC stop */
+ if (1ul == bM4_SYSREG_CMU_XTALSTDCR_XTALSTDIE)
+ {
+ if ((1ul == bM4_SYSREG_CMU_XTALSTDSR_XTALSTDF) && (VSSEL130 & BIT_MASK_21))
+ {
+ MainOscStop_IrqHandler();
+ }
+ }
+ /* Wakeup timer */
+ if ((1ul == bM4_WKTM_CR_WKOVF) && (VSSEL130 & BIT_MASK_22))
+ {
+ WakeupTimer_IrqHandler();
+ }
+ /* SWDT */
+ if ((M4_SWDT->SR & (BIT_MASK_16 | BIT_MASK_17)) && (VSSEL130 & BIT_MASK_23))
+ {
+ Swdt_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.131 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ131_Handler(void)
+{
+ uint32_t VSSEL131 = M4_INTC->VSSEL131;
+ uint32_t u32Tmp1 = 0ul;
+ uint32_t u32Tmp2 = 0ul;
+ /* Timer6 Ch.1 A compare match */
+ if (1ul == bM4_TMR61_ICONR_INTENA)
+ {
+ if ((1ul == bM4_TMR61_STFLR_CMAF) && (VSSEL131 & BIT_MASK_00))
+ {
+ Timer61GCMA_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 B compare match */
+ if (1ul == bM4_TMR61_ICONR_INTENB)
+ {
+ if ((1ul == bM4_TMR61_STFLR_CMBF) && (VSSEL131 & BIT_MASK_01))
+ {
+ Timer61GCMB_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 C compare match */
+ if (1ul == bM4_TMR61_ICONR_INTENC)
+ {
+ if ((1ul == bM4_TMR61_STFLR_CMCF) && (VSSEL131 & BIT_MASK_02))
+ {
+ Timer61GCMC_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 D compare match */
+ if (1ul == bM4_TMR61_ICONR_INTEND)
+ {
+ if ((1ul == bM4_TMR61_STFLR_CMDF) && (VSSEL131 & BIT_MASK_03))
+ {
+ Timer61GCMD_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 E compare match */
+ if (1ul == bM4_TMR61_ICONR_INTENE)
+ {
+ if ((1ul == bM4_TMR61_STFLR_CMEF) && (VSSEL131 & BIT_MASK_04))
+ {
+ Timer61GCME_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 F compare match */
+ if (1ul == bM4_TMR61_ICONR_INTENF)
+ {
+ if ((1ul == bM4_TMR61_STFLR_CMFF) && (VSSEL131 & BIT_MASK_05))
+ {
+ Timer61GCMF_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 overflow */
+ if (1ul == bM4_TMR61_ICONR_INTENOVF)
+ {
+ if ((1ul == bM4_TMR61_STFLR_OVFF) && (VSSEL131 & BIT_MASK_06))
+ {
+ Timer61GOV_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 underflow */
+ if (1ul == bM4_TMR61_ICONR_INTENUDF)
+ {
+ if ((1ul == bM4_TMR61_STFLR_UDFF) && (VSSEL131 & BIT_MASK_07))
+ {
+ Timer61GUD_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 dead time */
+ if (1ul == bM4_TMR61_ICONR_INTENDTE)
+ {
+ if (((1ul == bM4_TMR61_STFLR_DTEF)) && (VSSEL131 & BIT_MASK_08))
+ {
+ Timer61GDT_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.1 A up-down compare match */
+ u32Tmp1 = (M4_TMR61->ICONR & (BIT_MASK_16 | BIT_MASK_17)) >> 7u;
+ u32Tmp2 = M4_TMR61->STFLR & (BIT_MASK_09 | BIT_MASK_10);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL131 & BIT_MASK_11))
+ {
+ Timer61SCMA_IrqHandler();
+ }
+ /* Timer6 Ch.1 B up-down compare match */
+ u32Tmp1 = (M4_TMR61->ICONR & (BIT_MASK_18 | BIT_MASK_19)) >> 7u;
+ u32Tmp2 = M4_TMR61->STFLR & (BIT_MASK_11 | BIT_MASK_12);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL131 & BIT_MASK_12))
+ {
+ Timer61SCMB_IrqHandler();
+ }
+ /* Timer6 Ch.2 A compare match */
+ if (1ul == bM4_TMR62_ICONR_INTENA)
+ {
+ if ((1ul == bM4_TMR62_STFLR_CMAF) && (VSSEL131 & BIT_MASK_16))
+ {
+ Timer62GCMA_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 B compare match */
+ if (1ul == bM4_TMR62_ICONR_INTENB)
+ {
+ if ((1ul == bM4_TMR62_STFLR_CMBF) && (VSSEL131 & BIT_MASK_17))
+ {
+ Timer62GCMB_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 C compare match */
+ if (1ul == bM4_TMR62_ICONR_INTENC)
+ {
+ if ((1ul == bM4_TMR62_STFLR_CMCF) && (VSSEL131 & BIT_MASK_18))
+ {
+ Timer62GCMC_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 D compare match */
+ if (1ul == bM4_TMR62_ICONR_INTEND)
+ {
+ if ((1ul == bM4_TMR62_STFLR_CMDF) && (VSSEL131 & BIT_MASK_19))
+ {
+ Timer62GCMD_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 E compare match */
+ if (1ul == bM4_TMR62_ICONR_INTENE)
+ {
+ if ((1ul == bM4_TMR62_STFLR_CMEF) && (VSSEL131 & BIT_MASK_20))
+ {
+ Timer62GCME_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 F compare match */
+ if (1ul == bM4_TMR62_ICONR_INTENF)
+ {
+ if ((1ul == bM4_TMR62_STFLR_CMFF) && (VSSEL131 & BIT_MASK_21))
+ {
+ Timer62GCMF_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 overflow */
+ if (1ul == bM4_TMR62_ICONR_INTENOVF)
+ {
+ if ((1ul == bM4_TMR62_STFLR_OVFF) && (VSSEL131 & BIT_MASK_22))
+ {
+ Timer62GOV_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 underflow */
+ if (1ul == bM4_TMR62_ICONR_INTENUDF)
+ {
+ if ((1ul == bM4_TMR62_STFLR_UDFF) && (VSSEL131 & BIT_MASK_23))
+ {
+ Timer62GUD_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 dead time */
+ if (1ul == bM4_TMR62_ICONR_INTENDTE)
+ {
+ if (((1ul == bM4_TMR62_STFLR_DTEF)) && (VSSEL131 & BIT_MASK_24))
+ {
+ Timer62GDT_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.2 A up-down compare match */
+ u32Tmp1 = (M4_TMR62->ICONR & (BIT_MASK_16 | BIT_MASK_17)) >> 7u;
+ u32Tmp2 = M4_TMR62->STFLR & (BIT_MASK_09 | BIT_MASK_10);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL131 & BIT_MASK_27))
+ {
+ Timer62SCMA_IrqHandler();
+ }
+ /* Timer6 Ch.2 B up-down compare match */
+ u32Tmp1 = (M4_TMR62->ICONR & (BIT_MASK_18 | BIT_MASK_19)) >> 7u;
+ u32Tmp2 = M4_TMR62->STFLR & (BIT_MASK_11 | BIT_MASK_12);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL131 & BIT_MASK_28))
+ {
+ Timer62SCMB_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.132 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ132_Handler(void)
+{
+ uint32_t VSSEL132 = M4_INTC->VSSEL132;
+ uint32_t u32Tmp1 = 0ul;
+ uint32_t u32Tmp2 = 0ul;
+ /* Timer6 Ch.3 A compare match */
+ if (1ul == bM4_TMR63_ICONR_INTENA)
+ {
+ if ((1ul == bM4_TMR63_STFLR_CMAF) && (VSSEL132 & BIT_MASK_00))
+ {
+ Timer63GCMA_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 B compare match */
+ if (1ul == bM4_TMR63_ICONR_INTENB)
+ {
+ if ((1ul == bM4_TMR63_STFLR_CMBF) && (VSSEL132 & BIT_MASK_01))
+ {
+ Timer63GCMB_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 C compare match */
+ if (1ul == bM4_TMR63_ICONR_INTENC)
+ {
+ if ((1ul == bM4_TMR63_STFLR_CMCF) && (VSSEL132 & BIT_MASK_02))
+ {
+ Timer63GCMC_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 D compare match */
+ if (1ul == bM4_TMR63_ICONR_INTEND)
+ {
+ if ((1ul == bM4_TMR63_STFLR_CMDF) && (VSSEL132 & BIT_MASK_03))
+ {
+ Timer63GCMD_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 E compare match */
+ if (1ul == bM4_TMR63_ICONR_INTENE)
+ {
+ if ((1ul == bM4_TMR63_STFLR_CMEF) && (VSSEL132 & BIT_MASK_04))
+ {
+ Timer63GCME_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 F compare match */
+ if (1ul == bM4_TMR63_ICONR_INTENF)
+ {
+ if ((1ul == bM4_TMR63_STFLR_CMFF) && (VSSEL132 & BIT_MASK_05))
+ {
+ Timer63GCMF_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 overflow */
+ if (1ul == bM4_TMR63_ICONR_INTENOVF)
+ {
+ if ((1ul == bM4_TMR63_STFLR_OVFF) && (VSSEL132 & BIT_MASK_06))
+ {
+ Timer63GOV_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 underflow */
+ if (1ul == bM4_TMR63_ICONR_INTENUDF)
+ {
+ if ((1ul == bM4_TMR63_STFLR_UDFF) && (VSSEL132 & BIT_MASK_07))
+ {
+ Timer63GUD_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 dead time */
+ if (1ul == bM4_TMR63_ICONR_INTENDTE)
+ {
+ if (((1ul == bM4_TMR63_STFLR_DTEF)) && (VSSEL132 & BIT_MASK_08))
+ {
+ Timer63GDT_IrqHandler();
+ }
+ }
+ /* Timer6 Ch.3 A up-down compare match */
+ u32Tmp1 = (M4_TMR63->ICONR & (BIT_MASK_16 | BIT_MASK_17)) >> 7u;
+ u32Tmp2 = M4_TMR63->STFLR & (BIT_MASK_09 | BIT_MASK_10);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL132 & BIT_MASK_11))
+ {
+ Timer63SCMA_IrqHandler();
+ }
+ /* Timer6 Ch.3 B up-down compare match */
+ u32Tmp1 = (M4_TMR63->ICONR & (BIT_MASK_18 | BIT_MASK_19)) >> 7u;
+ u32Tmp2 = M4_TMR63->STFLR & (BIT_MASK_11 | BIT_MASK_12);
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL132 & BIT_MASK_12))
+ {
+ Timer63SCMB_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.136 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ136_Handler(void)
+{
+ uint32_t u32Tmp1 = 0ul;
+ uint32_t u32Tmp2 = 0ul;
+ uint32_t VSSEL136 = M4_INTC->VSSEL136;
+
+ u32Tmp1 = M4_TMRA1->BCSTR;
+ /* TimerA Ch.1 overflow */
+ if ((u32Tmp1 & BIT_MASK_12) && (u32Tmp1 & BIT_MASK_14) && (VSSEL136 & BIT_MASK_00))
+ {
+ TimerA1OV_IrqHandler();
+ }
+ /* TimerA Ch.1 underflow */
+ if ((u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_15) && (VSSEL136 & BIT_MASK_01))
+ {
+ TimerA1UD_IrqHandler();
+ }
+ u32Tmp1 = M4_TMRA1->ICONR;
+ u32Tmp2 = M4_TMRA1->STFLR;
+ /* TimerA Ch.1 compare match */
+ if ((u32Tmp1 & u32Tmp2 & 0xFFul) && (VSSEL136 & BIT_MASK_02))
+ {
+ TimerA1CMP_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMRA2->BCSTR;
+ /* TimerA Ch.2 overflow */
+ if ((u32Tmp1 & BIT_MASK_12) && (u32Tmp1 & BIT_MASK_14) && (VSSEL136 & BIT_MASK_03))
+ {
+ TimerA2OV_IrqHandler();
+ }
+ /* TimerA Ch.2 underflow */
+ if ((u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_15) && (VSSEL136 & BIT_MASK_04))
+ {
+ TimerA2UD_IrqHandler();
+ }
+ u32Tmp1 = M4_TMRA2->ICONR;
+ u32Tmp2 = M4_TMRA2->STFLR;
+ /* TimerA Ch.2 compare match */
+ if ((u32Tmp1 & u32Tmp2 & 0xFFul) && (VSSEL136 & BIT_MASK_05))
+ {
+ TimerA2CMP_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMRA3->BCSTR;
+ /* TimerA Ch.3 overflow */
+ if ((u32Tmp1 & BIT_MASK_12) && (u32Tmp1 & BIT_MASK_14) && (VSSEL136 & BIT_MASK_06))
+ {
+ TimerA3OV_IrqHandler();
+ }
+ /* TimerA Ch.3 underflow */
+ if ((u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_15) && (VSSEL136 & BIT_MASK_07))
+ {
+ TimerA3UD_IrqHandler();
+ }
+ u32Tmp1 = M4_TMRA3->ICONR;
+ u32Tmp2 = M4_TMRA3->STFLR;
+ /* TimerA Ch.3 compare match */
+ if ((u32Tmp1 & u32Tmp2 & 0xFFul) && (VSSEL136 & BIT_MASK_08))
+ {
+ TimerA3CMP_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMRA4->BCSTR;
+ /* TimerA Ch.4 overflow */
+ if ((u32Tmp1 & BIT_MASK_12) && (u32Tmp1 & BIT_MASK_14) && (VSSEL136 & BIT_MASK_09))
+ {
+ TimerA4OV_IrqHandler();
+ }
+ /* TimerA Ch.4 underflow */
+ if ((u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_15) && (VSSEL136 & BIT_MASK_10))
+ {
+ TimerA4UD_IrqHandler();
+ }
+ u32Tmp1 = M4_TMRA4->ICONR;
+ u32Tmp2 = M4_TMRA4->STFLR;
+ /* TimerA Ch.4 compare match */
+ if ((u32Tmp1 & u32Tmp2 & 0xFFul) && (VSSEL136 & BIT_MASK_11))
+ {
+ TimerA4CMP_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMRA5->BCSTR;
+ /* TimerA Ch.5 overflow */
+ if ((u32Tmp1 & BIT_MASK_12) && (u32Tmp1 & BIT_MASK_14) && (VSSEL136 & BIT_MASK_12))
+ {
+ TimerA5OV_IrqHandler();
+ }
+ /* TimerA Ch.5 underflow */
+ if ((u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_15) && (VSSEL136 & BIT_MASK_13))
+ {
+ TimerA5UD_IrqHandler();
+ }
+ u32Tmp1 = M4_TMRA5->ICONR;
+ u32Tmp2 = M4_TMRA5->STFLR;
+ /* TimerA Ch.5 compare match */
+ if ((u32Tmp1 & u32Tmp2 & 0xFFul) && (VSSEL136 & BIT_MASK_14))
+ {
+ TimerA5CMP_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMRA6->BCSTR;
+ /* TimerA Ch.6 overflow */
+ if ((u32Tmp1 & BIT_MASK_12) && (u32Tmp1 & BIT_MASK_14) && (VSSEL136 & BIT_MASK_16))
+ {
+ TimerA6OV_IrqHandler();
+ }
+ /* TimerA Ch.6 underflow */
+ if ((u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_15) && (VSSEL136 & BIT_MASK_17))
+ {
+ TimerA6UD_IrqHandler();
+ }
+ u32Tmp1 = M4_TMRA6->ICONR;
+ u32Tmp2 = M4_TMRA6->STFLR;
+ /* TimerA Ch.6 compare match */
+ if ((u32Tmp1 & u32Tmp2 & 0xFFul) && (VSSEL136 & BIT_MASK_18))
+ {
+ TimerA6CMP_IrqHandler();
+ }
+ /* USBFS global interrupt */
+ if(1ul == bM4_USBFS_GAHBCFG_GINTMSK)
+ {
+ u32Tmp1 = M4_USBFS->GINTMSK & 0xF77CFCFBul;
+ u32Tmp2 = M4_USBFS->GINTSTS & 0xF77CFCFBul;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL136 & BIT_MASK_19))
+ {
+ UsbGlobal_IrqHandler();
+ }
+ }
+
+ u32Tmp1 = M4_USART1->SR;
+ u32Tmp2 = M4_USART1->CR1;
+ /* USART Ch.1 Receive error */
+ if ((u32Tmp2 & BIT_MASK_05) && (u32Tmp1 & (BIT_MASK_00 | BIT_MASK_01 | BIT_MASK_03)) && (VSSEL136 & BIT_MASK_22))
+ {
+ Usart1RxErr_IrqHandler();
+ }
+ /* USART Ch.1 Receive completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_05) && (VSSEL136 & BIT_MASK_23))
+ {
+ Usart1RxEnd_IrqHandler();
+ }
+ /* USART Ch.1 Transmit data empty */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_07) && (VSSEL136 & BIT_MASK_24))
+ {
+ Usart1TxEmpty_IrqHandler();
+ }
+ /* USART Ch.1 Transmit completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_06) && (VSSEL136 & BIT_MASK_25))
+ {
+ Usart1TxEnd_IrqHandler();
+ }
+ /* USART Ch.1 Receive timeout */
+ if ((u32Tmp2 & BIT_MASK_01) && (u32Tmp1 & BIT_MASK_08) && (VSSEL136 & BIT_MASK_26))
+ {
+ Usart1RxTO_IrqHandler();
+ }
+
+ u32Tmp1 = M4_USART2->SR;
+ u32Tmp2 = M4_USART2->CR1;
+ /* USART Ch.2 Receive error */
+ if ((u32Tmp2 & BIT_MASK_05) && (u32Tmp1 & (BIT_MASK_00 | BIT_MASK_01 | BIT_MASK_03)) && (VSSEL136 & BIT_MASK_27))
+ {
+ Usart2RxErr_IrqHandler();
+ }
+ /* USART Ch.2 Receive completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_05) && (VSSEL136 & BIT_MASK_28))
+ {
+ Usart2RxEnd_IrqHandler();
+ }
+ /* USART Ch.2 Transmit data empty */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_07) && (VSSEL136 & BIT_MASK_29))
+ {
+ Usart2TxEmpty_IrqHandler();
+ }
+ /* USART Ch.2 Transmit completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_06) && (VSSEL136 & BIT_MASK_30))
+ {
+ Usart2TxEnd_IrqHandler();
+ }
+ /* USART Ch.2 Receive timeout */
+ if ((u32Tmp2 & BIT_MASK_01) && (u32Tmp1 & BIT_MASK_08) && (VSSEL136 & BIT_MASK_31))
+ {
+ Usart2RxTO_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.137 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ137_Handler(void)
+{
+ uint32_t u32Tmp1 = 0ul;
+ uint32_t u32Tmp2 = 0ul;
+ uint32_t VSSEL137 = M4_INTC->VSSEL137;
+
+ u32Tmp1 = M4_USART3->SR;
+ u32Tmp2 = M4_USART3->CR1;
+ /* USART Ch.3 Receive error */
+ if ((u32Tmp2 & BIT_MASK_05) && (u32Tmp1 & (BIT_MASK_00 | BIT_MASK_01 | BIT_MASK_03)) && (VSSEL137 & BIT_MASK_00))
+ {
+ Usart3RxErr_IrqHandler();
+ }
+ /* USART Ch.3 Receive completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_05) && (VSSEL137 & BIT_MASK_01))
+ {
+ Usart3RxEnd_IrqHandler();
+ }
+ /* USART Ch.3 Transmit data empty */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_07) && (VSSEL137 & BIT_MASK_02))
+ {
+ Usart3TxEmpty_IrqHandler();
+ }
+ /* USART Ch.3 Transmit completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_06) && (VSSEL137 & BIT_MASK_03))
+ {
+ Usart3TxEnd_IrqHandler();
+ }
+ /* USART Ch.3 Receive timeout */
+ if ((u32Tmp2 & BIT_MASK_01) && (u32Tmp1 & BIT_MASK_08) && (VSSEL137 & BIT_MASK_04))
+ {
+ Usart3RxTO_IrqHandler();
+ }
+
+ u32Tmp1 = M4_USART4->SR;
+ u32Tmp2 = M4_USART4->CR1;
+ /* USART Ch.4 Receive error */
+ if ((u32Tmp2 & BIT_MASK_05) && (u32Tmp1 & (BIT_MASK_00 | BIT_MASK_01 | BIT_MASK_03)) && (VSSEL137 & BIT_MASK_05))
+ {
+ Usart4RxErr_IrqHandler();
+ }
+ /* USART Ch.4 Receive completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_05) && (VSSEL137 & BIT_MASK_06))
+ {
+ Usart4RxEnd_IrqHandler();
+ }
+ /* USART Ch.4 Transmit data empty */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_07) && (VSSEL137 & BIT_MASK_07))
+ {
+ Usart4TxEmpty_IrqHandler();
+ }
+ /* USART Ch.4 Transmit completed */
+ if ((u32Tmp2 & u32Tmp1 & BIT_MASK_06) && (VSSEL137 & BIT_MASK_08))
+ {
+ Usart4TxEnd_IrqHandler();
+ }
+ /* USART Ch.4 Receive timeout */
+ if ((u32Tmp2 & BIT_MASK_01) && (u32Tmp1 & BIT_MASK_08) && (VSSEL137 & BIT_MASK_09))
+ {
+ Usart4RxTO_IrqHandler();
+ }
+
+ u32Tmp1 = M4_SPI1->CR1;
+ u32Tmp2 = M4_SPI1->SR;
+ /* SPI Ch.1 Receive completed */
+ if ((u32Tmp1 & BIT_MASK_10) && (u32Tmp2 & BIT_MASK_07) && (VSSEL137 & BIT_MASK_11))
+ {
+ Spi1RxEnd_IrqHandler();
+ }
+ /* SPI Ch.1 Transmit buf empty */
+ if ((u32Tmp1 & BIT_MASK_09) && (u32Tmp2 & BIT_MASK_05) && (VSSEL137 & BIT_MASK_12))
+ {
+ Spi1TxEmpty_IrqHandler();
+ }
+ /* SPI Ch.1 bus idle */
+ if ((u32Tmp1 & BIT_MASK_11) && (!(u32Tmp2 & BIT_MASK_01)) && (VSSEL137 & BIT_MASK_13))
+ {
+ Spi1Idle_IrqHandler();
+ }
+ /* SPI Ch.1 parity/overflow/underflow/mode error */
+ if ((u32Tmp1 & BIT_MASK_08) && \
+ ((u32Tmp2 & (BIT_MASK_00 | BIT_MASK_02 | BIT_MASK_03 | BIT_MASK_04))) && \
+ (VSSEL137 & BIT_MASK_14))
+ {
+ Spi1Err_IrqHandler();
+ }
+
+ u32Tmp1 = M4_SPI2->CR1;
+ u32Tmp2 = M4_SPI2->SR;
+ /* SPI Ch.2 Receive completed */
+ if ((u32Tmp1 & BIT_MASK_10) && (u32Tmp2 & BIT_MASK_07) && (VSSEL137 & BIT_MASK_16))
+ {
+ Spi2RxEnd_IrqHandler();
+ }
+ /* SPI Ch.2 Transmit buf empty */
+ if ((u32Tmp1 & BIT_MASK_09) && (u32Tmp2 & BIT_MASK_05) && (VSSEL137 & BIT_MASK_17))
+ {
+ Spi2TxEmpty_IrqHandler();
+ }
+ /* SPI Ch.2 bus idle */
+ if ((u32Tmp1 & BIT_MASK_11) && (!(u32Tmp2 & BIT_MASK_01)) && (VSSEL137 & BIT_MASK_18))
+ {
+ Spi2Idle_IrqHandler();
+ }
+ /* SPI Ch.2 parity/overflow/underflow/mode error */
+ if ((u32Tmp1 & BIT_MASK_08) && \
+ ((u32Tmp2 & (BIT_MASK_00 | BIT_MASK_02 | BIT_MASK_03 | BIT_MASK_04))) && \
+ (VSSEL137 & BIT_MASK_19))
+ {
+ Spi2Err_IrqHandler();
+ }
+
+ u32Tmp1 = M4_SPI3->CR1;
+ u32Tmp2 = M4_SPI3->SR;
+ /* SPI Ch.3 Receive completed */
+ if ((u32Tmp1 & BIT_MASK_10) && (u32Tmp2 & BIT_MASK_07) && (VSSEL137 & BIT_MASK_21))
+ {
+ Spi3RxEnd_IrqHandler();
+ }
+ /* SPI Ch.3 Transmit buf empty */
+ if ((u32Tmp1 & BIT_MASK_09) && (u32Tmp2 & BIT_MASK_05) && (VSSEL137 & BIT_MASK_22))
+ {
+ Spi3TxEmpty_IrqHandler();
+ }
+ /* SPI Ch.3 bus idle */
+ if ((u32Tmp1 & BIT_MASK_11) && (!(u32Tmp2 & BIT_MASK_01)) && (VSSEL137 & BIT_MASK_23))
+ {
+ Spi3Idle_IrqHandler();
+ }
+ /* SPI Ch.3 parity/overflow/underflow/mode error */
+ if ((u32Tmp1 & BIT_MASK_08) && \
+ ((u32Tmp2 & (BIT_MASK_00 | BIT_MASK_02 | BIT_MASK_03 | BIT_MASK_04))) && \
+ (VSSEL137 & BIT_MASK_24))
+ {
+ Spi3Err_IrqHandler();
+ }
+
+ u32Tmp1 = M4_SPI4->CR1;
+ u32Tmp2 = M4_SPI4->SR;
+ /* SPI Ch.4 Receive completed */
+ if ((u32Tmp1 & BIT_MASK_10) && (u32Tmp2 & BIT_MASK_07) && (VSSEL137 & BIT_MASK_26))
+ {
+ Spi4RxEnd_IrqHandler();
+ }
+ /* SPI Ch.4 Transmit buf empty */
+ if ((u32Tmp1 & BIT_MASK_09) && (u32Tmp2 & BIT_MASK_05) && (VSSEL137 & BIT_MASK_27))
+ {
+ Spi4TxEmpty_IrqHandler();
+ }
+ /* SPI Ch.4 bus idle */
+ if ((u32Tmp1 & BIT_MASK_11) && (!(u32Tmp2 & BIT_MASK_01)) && (VSSEL137 & BIT_MASK_28))
+ {
+ Spi4Idle_IrqHandler();
+ }
+ /* SPI Ch.4 parity/overflow/underflow/mode error */
+ if ((u32Tmp1 & BIT_MASK_08) && \
+ ((u32Tmp2 & (BIT_MASK_00 | BIT_MASK_02 | BIT_MASK_03 | BIT_MASK_04))) && \
+ (VSSEL137 & BIT_MASK_29))
+ {
+ Spi4Err_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.138 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ138_Handler(void)
+{
+ uint32_t u32Tmp1 = 0u;
+ uint32_t VSSEL138 = M4_INTC->VSSEL138;
+
+ u32Tmp1 = M4_TMR41->OCSRU;
+ /* Timer4 Ch.1 U phase higher compare match */
+ if ((VSSEL138 & BIT_MASK_00) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer41GCMUH_IrqHandler();
+ }
+ /* Timer4 Ch.1 U phase lower compare match */
+ if ((VSSEL138 & BIT_MASK_01) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer41GCMUL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR41->OCSRV;
+ /* Timer4 Ch.1 V phase higher compare match */
+ if ((VSSEL138 & BIT_MASK_02) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer41GCMVH_IrqHandler();
+ }
+ /* Timer4 Ch.1 V phase lower compare match */
+ if ((VSSEL138 & BIT_MASK_03) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer41GCMVL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR41->OCSRW;
+ /* Timer4 Ch.1 W phase higher compare match */
+ if ((VSSEL138 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer41GCMWH_IrqHandler();
+ }
+ /* Timer4 Ch.1 W phase lower compare match */
+ if ((VSSEL138 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer41GCMWL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR41->CCSR;
+ /* Timer4 Ch.1 overflow */
+ if ((VSSEL138 & BIT_MASK_06) && (u32Tmp1 & BIT_MASK_08) && (u32Tmp1 & BIT_MASK_09))
+ {
+ Timer41GOV_IrqHandler();
+ }
+ /* Timer4 Ch.1 underflow */
+ if ((VSSEL138 & BIT_MASK_07) && (u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_14))
+ {
+ Timer41GUD_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR41->RCSR;
+ /* Timer4 Ch.1 U phase reload */
+ if ((VSSEL138 & BIT_MASK_08) && (~(u32Tmp1 & BIT_MASK_00)) && (u32Tmp1 & BIT_MASK_04))
+ {
+ Timer41ReloadU_IrqHandler();
+ }
+ /* Timer4 Ch.1 V phase reload */
+ if ((VSSEL138 & BIT_MASK_09) && (~(u32Tmp1 & BIT_MASK_01)) && (u32Tmp1 & BIT_MASK_08))
+ {
+ Timer41ReloadV_IrqHandler();
+ }
+ /* Timer4 Ch.1 W phase reload */
+ if ((VSSEL138 & BIT_MASK_10) && (~(u32Tmp1 & BIT_MASK_02)) && (u32Tmp1 & BIT_MASK_12))
+ {
+ Timer41ReloadW_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR42->OCSRU;
+ /* Timer4 Ch.2 U phase higher compare match */
+ if ((VSSEL138 & BIT_MASK_16) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer41GCMUH_IrqHandler();
+ }
+ /* Timer4 Ch.2 U phase lower compare match */
+ if ((VSSEL138 & BIT_MASK_17) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer41GCMUL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR42->OCSRV;
+ /* Timer4 Ch.2 V phase higher compare match */
+ if ((VSSEL138 & BIT_MASK_18) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer42GCMVH_IrqHandler();
+ }
+ /* Timer4 Ch.2 V phase lower compare match */
+ if ((VSSEL138 & BIT_MASK_19) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer42GCMVL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR42->OCSRW;
+ /* Timer4 Ch.2 W phase higher compare match */
+ if ((VSSEL138 & BIT_MASK_20) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer42GCMWH_IrqHandler();
+ }
+ /* Timer4 Ch.2 W phase lower compare match */
+ if ((VSSEL138 & BIT_MASK_21) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer42GCMWL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR42->CCSR;
+ /* Timer4 Ch.2 overflow */
+ if ((VSSEL138 & BIT_MASK_22) && (u32Tmp1 & BIT_MASK_08) && (u32Tmp1 & BIT_MASK_09))
+ {
+ Timer42GOV_IrqHandler();
+ }
+ /* Timer4 Ch.2 underflow */
+ if ((VSSEL138 & BIT_MASK_23) && (u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_14))
+ {
+ Timer42GUD_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR42->RCSR;
+ /* Timer4 Ch.2 U phase reload */
+ if ((VSSEL138 & BIT_MASK_24) && (~(u32Tmp1 & BIT_MASK_00)) && (u32Tmp1 & BIT_MASK_04))
+ {
+ Timer42ReloadU_IrqHandler();
+ }
+ /* Timer4 Ch.2 V phase reload */
+ if ((VSSEL138 & BIT_MASK_25) && (~(u32Tmp1 & BIT_MASK_01)) && (u32Tmp1 & BIT_MASK_08))
+ {
+ Timer42ReloadV_IrqHandler();
+ }
+ /* Timer4 Ch.2 W phase reload */
+ if ((VSSEL138 & BIT_MASK_26) && (~(u32Tmp1 & BIT_MASK_02)) && (u32Tmp1 & BIT_MASK_12))
+ {
+ Timer42ReloadW_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.139 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ139_Handler(void)
+{
+ uint32_t u32Tmp1 = 0u;
+ uint32_t VSSEL139 = M4_INTC->VSSEL139;
+
+ u32Tmp1 = M4_TMR43->OCSRU;
+ /* Timer4 Ch.3 U phase higher compare match */
+ if ((VSSEL139 & BIT_MASK_00) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer43GCMUH_IrqHandler();
+ }
+ /* Timer4 Ch.3 U phase lower compare match */
+ if ((VSSEL139 & BIT_MASK_01) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer43GCMUL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR43->OCSRV;
+ /* Timer4 Ch.3 V phase higher compare match */
+ if ((VSSEL139 & BIT_MASK_02) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer43GCMVH_IrqHandler();
+ }
+ /* Timer4 Ch.3 V phase lower compare match */
+ if ((VSSEL139 & BIT_MASK_03) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer43GCMVL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR43->OCSRW;
+ /* Timer4 Ch.3 W phase higher compare match */
+ if ((VSSEL139 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_04) && (u32Tmp1 & BIT_MASK_06))
+ {
+ Timer43GCMWH_IrqHandler();
+ }
+ /* Timer4 Ch.3 W phase lower compare match */
+ if ((VSSEL139 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_05) && (u32Tmp1 & BIT_MASK_07))
+ {
+ Timer43GCMWL_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR43->CCSR;
+ /* Timer4 Ch.3 overflow */
+ if ((VSSEL139 & BIT_MASK_06) && (u32Tmp1 & BIT_MASK_08) && (u32Tmp1 & BIT_MASK_09))
+ {
+ Timer43GOV_IrqHandler();
+ }
+ /* Timer4 Ch.3 underflow */
+ if ((VSSEL139 & BIT_MASK_07) && (u32Tmp1 & BIT_MASK_13) && (u32Tmp1 & BIT_MASK_14))
+ {
+ Timer43GUD_IrqHandler();
+ }
+
+ u32Tmp1 = M4_TMR43->RCSR;
+ /* Timer4 Ch.3 U phase reload */
+ if ((VSSEL139 & BIT_MASK_08) && (~(u32Tmp1 & BIT_MASK_00)) && (u32Tmp1 & BIT_MASK_04))
+ {
+ Timer41ReloadU_IrqHandler();
+ }
+ /* Timer4 Ch.3 V phase reload */
+ if ((VSSEL139 & BIT_MASK_09) && (~(u32Tmp1 & BIT_MASK_01)) && (u32Tmp1 & BIT_MASK_08))
+ {
+ Timer43ReloadV_IrqHandler();
+ }
+ /* Timer4 Ch.3 W phase reload */
+ if ((VSSEL139 & BIT_MASK_10) && (~(u32Tmp1 & BIT_MASK_02)) && (u32Tmp1 & BIT_MASK_12))
+ {
+ Timer43ReloadW_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.140 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ140_Handler(void)
+{
+ uint32_t VSSEL140 = M4_INTC->VSSEL140;
+ uint32_t u32Tmp1 = 0u;
+ uint32_t u32Tmp2 = 0u;
+ /* EMB1 */
+ u32Tmp1 = M4_EMB1->STAT & 0x0000000Ful;
+ u32Tmp2 = M4_EMB1->INTEN & 0x0000000Ful;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL140 & BIT_MASK_06))
+ {
+ Emb1_IrqHandler();
+ }
+ /* EMB2 */
+ u32Tmp1 = M4_EMB2->STAT & 0x0000000Ful;
+ u32Tmp2 = M4_EMB2->INTEN & 0x0000000Ful;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL140 & BIT_MASK_07))
+ {
+ Emb2_IrqHandler();
+ }
+ /* EMB3 */
+ u32Tmp1 = M4_EMB3->STAT & 0x0000000Ful;
+ u32Tmp2 = M4_EMB3->INTEN & 0x0000000Ful;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL140 & BIT_MASK_08))
+ {
+ Emb3_IrqHandler();
+ }
+ /* EMB4*/
+ u32Tmp1 = M4_EMB4->STAT & 0x0000000Ful;
+ u32Tmp2 = M4_EMB4->INTEN & 0x0000000Ful;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL140 & BIT_MASK_09))
+ {
+ Emb4_IrqHandler();
+ }
+
+ /* I2S Ch.1 Transmit */
+ if(1ul == bM4_I2S1_CTRL_TXIE)
+ {
+ if ((1ul == bM4_I2S1_SR_TXBA) && (VSSEL140 & BIT_MASK_16))
+ {
+ I2s1Tx_IrqHandler();
+ }
+ }
+ /* I2S Ch.1 Receive */
+ if(1ul == bM4_I2S1_CTRL_RXIE)
+ {
+ if ((1ul == bM4_I2S1_SR_RXBA) && (VSSEL140 & BIT_MASK_17))
+ {
+ I2s1Rx_IrqHandler();
+ }
+ }
+ /* I2S Ch.1 Error */
+ if(1ul == bM4_I2S1_CTRL_EIE)
+ {
+ if ((M4_I2S1->ER & (BIT_MASK_00 | BIT_MASK_01)) && (VSSEL140 & BIT_MASK_18))
+ {
+ I2s1Err_IrqHandler();
+ }
+ }
+ /* I2S Ch.2 Transmit */
+ if(1ul == bM4_I2S2_CTRL_TXIE)
+ {
+ if ((1ul == bM4_I2S2_SR_TXBA) && (VSSEL140 & BIT_MASK_19))
+ {
+ I2s2Tx_IrqHandler();
+ }
+ }
+ /* I2S Ch.2 Receive */
+ if(1ul == bM4_I2S2_CTRL_RXIE)
+ {
+ if ((1ul == bM4_I2S2_SR_RXBA) && (VSSEL140 & BIT_MASK_20))
+ {
+ I2s2Rx_IrqHandler();
+ }
+ }
+ /* I2S Ch.2 Error */
+ if(1ul == bM4_I2S2_CTRL_EIE)
+ {
+ if ((M4_I2S2->ER & (BIT_MASK_00 | BIT_MASK_01)) && (VSSEL140 & BIT_MASK_21))
+ {
+ I2s2Err_IrqHandler();
+ }
+ }
+ /* I2S Ch.3 Transmit */
+ if(1ul == bM4_I2S3_CTRL_TXIE)
+ {
+ if ((1ul == bM4_I2S3_SR_TXBA) && (VSSEL140 & BIT_MASK_22))
+ {
+ I2s3Tx_IrqHandler();
+ }
+ }
+ /* I2S Ch.3 Receive */
+ if(1ul == bM4_I2S3_CTRL_RXIE)
+ {
+ if ((1ul == bM4_I2S3_SR_RXBA) && (VSSEL140 & BIT_MASK_23))
+ {
+ I2s3Rx_IrqHandler();
+ }
+ }
+ /* I2S Ch.3 Error */
+ if(1ul == bM4_I2S3_CTRL_EIE)
+ {
+ if ((M4_I2S3->ER & (BIT_MASK_00 | BIT_MASK_01)) && (VSSEL140 & BIT_MASK_24))
+ {
+ I2s3Err_IrqHandler();
+ }
+ }
+ /* I2S Ch.4 Transmit */
+ if(1ul == bM4_I2S4_CTRL_TXIE)
+ {
+ if ((1ul == bM4_I2S4_SR_TXBA) && (VSSEL140 & BIT_MASK_25))
+ {
+ I2s4Tx_IrqHandler();
+ }
+ }
+ /* I2S Ch.4 Receive */
+ if(1ul == bM4_I2S4_CTRL_RXIE)
+ {
+ if ((1ul == bM4_I2S4_SR_RXBA) && (VSSEL140 & BIT_MASK_26))
+ {
+ I2s4Rx_IrqHandler();
+ }
+ }
+ /* I2S Ch.4 Error */
+ if(1ul == bM4_I2S4_CTRL_EIE)
+ {
+ if ((M4_I2S4->ER & (BIT_MASK_00 | BIT_MASK_01)) && (VSSEL140 & BIT_MASK_27))
+ {
+ I2s4Err_IrqHandler();
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.141 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ141_Handler(void)
+{
+ uint32_t VSSEL141 = M4_INTC->VSSEL141;
+ uint32_t u32Tmp1 = 0ul;
+ uint32_t u32Tmp2 = 0ul;
+ /* I2C Ch.1 Receive completed */
+ if(1ul == bM4_I2C1_CR2_RFULLIE)
+ {
+ if ((1ul == bM4_I2C1_SR_RFULLF) && (VSSEL141 & BIT_MASK_04))
+ {
+ I2c1RxEnd_IrqHandler();
+ }
+ }
+ /* I2C Ch.1 Transmit data empty */
+ if(1ul == bM4_I2C1_CR2_TEMPTYIE)
+ {
+ if ((1ul == bM4_I2C1_SR_TEMPTYF) && (VSSEL141 & BIT_MASK_05))
+ {
+ I2c1TxEmpty_IrqHandler();
+ }
+ }
+ /* I2C Ch.1 Transmit completed */
+ if(1ul == bM4_I2C1_CR2_TENDIE)
+ {
+ if ((1ul == bM4_I2C1_SR_TENDF) && (VSSEL141 & BIT_MASK_06))
+ {
+ I2c1TxEnd_IrqHandler();
+ }
+ }
+ /* I2C Ch.1 Error */
+ u32Tmp1 = M4_I2C1->CR2 & 0x00F05217ul;
+ u32Tmp2 = M4_I2C1->SR & 0x00F05217ul;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL141 & BIT_MASK_07))
+ {
+ I2c1Err_IrqHandler();
+ }
+ /* I2C Ch.2 Receive completed */
+ if(1ul == bM4_I2C2_CR2_RFULLIE)
+ {
+ if ((1ul == bM4_I2C2_SR_RFULLF) && (VSSEL141 & BIT_MASK_08))
+ {
+ I2c2RxEnd_IrqHandler();
+ }
+ }
+ /* I2C Ch.2 Transmit data empty */
+ if(1ul == bM4_I2C2_CR2_TEMPTYIE)
+ {
+ if ((1ul == bM4_I2C2_SR_TEMPTYF) && (VSSEL141 & BIT_MASK_09))
+ {
+ I2c2TxEmpty_IrqHandler();
+ }
+ }
+ /* I2C Ch.2 Transmit completed */
+ if(1ul == bM4_I2C2_CR2_TENDIE)
+ {
+ if ((1ul == bM4_I2C2_SR_TENDF) && (VSSEL141 & BIT_MASK_10))
+ {
+ I2c2TxEnd_IrqHandler();
+ }
+ }
+ /* I2C Ch.2 Error */
+ u32Tmp1 = M4_I2C2->CR2 & 0x00F05217ul;
+ u32Tmp2 = M4_I2C2->SR & 0x00F05217ul;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL141 & BIT_MASK_11))
+ {
+ I2c2Err_IrqHandler();
+ }
+ /* I2C Ch.3 Receive completed */
+ if(1ul == bM4_I2C3_CR2_RFULLIE)
+ {
+ if ((1ul == bM4_I2C3_SR_RFULLF) && (VSSEL141 & BIT_MASK_12))
+ {
+ I2c3RxEnd_IrqHandler();
+ }
+ }
+ /* I2C Ch.3 Transmit data empty */
+ if(1ul == bM4_I2C3_CR2_TEMPTYIE)
+ {
+ if ((1ul == bM4_I2C3_SR_TEMPTYF) && (VSSEL141 & BIT_MASK_13))
+ {
+ I2c3TxEmpty_IrqHandler();
+ }
+ }
+ /* I2C Ch.3 Transmit completed */
+ if(1ul == bM4_I2C3_CR2_TENDIE)
+ {
+ if ((1ul == bM4_I2C3_SR_TENDF) && (VSSEL141 & BIT_MASK_14))
+ {
+ I2c3TxEnd_IrqHandler();
+ }
+ }
+ /* I2C Ch.3 Error */
+ u32Tmp1 = M4_I2C3->CR2 & 0x00F05217ul;
+ u32Tmp2 = M4_I2C3->SR & 0x00F05217ul;
+ if ((u32Tmp1 & u32Tmp2) && (VSSEL141 & BIT_MASK_15))
+ {
+ I2c3Err_IrqHandler();
+ }
+ /* PVD Ch.1 detected */
+ if (1ul == M4_SYSREG->PWR_PVDDSR_f.PVD1DETFLG)
+ {
+ if((1ul == bM4_SYSREG_PWR_PVDDSR_PVD1DETFLG) && (VSSEL141 & BIT_MASK_17))
+ {
+ Pvd1_IrqHandler();
+ }
+ }
+ if (1ul == M4_SYSREG->PWR_PVDDSR_f.PVD2DETFLG)
+ {
+ /* PVD Ch.2 detected */
+ if((1ul == bM4_SYSREG_PWR_PVDDSR_PVD2DETFLG) && (VSSEL141 & BIT_MASK_18))
+ {
+ Pvd2_IrqHandler();
+ }
+ }
+ /* Freq. calculate error detected */
+ if(1ul == bM4_FCM_RIER_ERRIE)
+ {
+ if((1ul == bM4_FCM_SR_ERRF) && (VSSEL141 & BIT_MASK_20))
+ {
+ FcmErr_IrqHandler();
+ }
+ }
+ /* Freq. calculate completed */
+ if(1ul == bM4_FCM_RIER_MENDIE)
+ {
+ if((1ul == bM4_FCM_SR_MENDF) && (VSSEL141 & BIT_MASK_21))
+ {
+ FcmEnd_IrqHandler();
+ }
+ }
+ /* Freq. calculate overflow */
+ if(1ul == bM4_FCM_RIER_OVFIE)
+ {
+ if((1ul == bM4_FCM_SR_OVF) && (VSSEL141 & BIT_MASK_22))
+ {
+ FcmOV_IrqHandler();
+ }
+ }
+
+ /* WDT */
+ if ((M4_WDT->SR & (BIT_MASK_16 | BIT_MASK_17)) && (VSSEL141 & BIT_MASK_23))
+ {
+ Wdt_IrqHandler();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.142 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ142_Handler(void)
+{
+ uint32_t u32VSSEL142 = M4_INTC->VSSEL142;
+ uint16_t u16Tmp = 0u;
+ /* ADC unit.1 seq. A */
+ if (1ul == bM4_ADC1_ICR_EOCAIEN)
+ {
+ if ((1ul == bM4_ADC1_ISR_EOCAF) && (u32VSSEL142 & BIT_MASK_00))
+ {
+ ADC1A_IrqHandler();
+ }
+ }
+ /* ADC unit.1 seq. B */
+ if (1ul == bM4_ADC1_ICR_EOCBIEN)
+ {
+ if ((1ul == bM4_ADC1_ISR_EOCBF) && (u32VSSEL142 & BIT_MASK_01))
+ {
+ ADC1B_IrqHandler();
+ }
+ }
+ /* ADC unit.1 seq. A */
+ u16Tmp = M4_ADC1->AWDSR0;
+ if (1ul == bM4_ADC1_AWDCR_AWDIEN)
+ {
+ if (((1ul == bM4_ADC1_AWDSR1_AWDF16) || (u16Tmp)) && (u32VSSEL142 & BIT_MASK_02))
+ {
+ ADC1ChCmp_IrqHandler();
+ }
+ }
+ /* ADC unit.1 seq. cmp */
+ if (1ul == bM4_ADC1_AWDCR_AWDIEN)
+ {
+ if (((1ul == bM4_ADC1_AWDSR1_AWDF16) || (u16Tmp)) && (u32VSSEL142 & BIT_MASK_03))
+ {
+ ADC1SeqCmp_IrqHandler();
+ }
+ }
+
+ /* ADC unit.2 seq. A */
+ if (1ul == bM4_ADC2_ICR_EOCAIEN)
+ {
+ if ((1ul == bM4_ADC2_ISR_EOCAF) && (u32VSSEL142 & BIT_MASK_04))
+ {
+ ADC2A_IrqHandler();
+ }
+ }
+ /* ADC unit.2 seq. B */
+ if (1ul == bM4_ADC2_ICR_EOCBIEN)
+ {
+ if ((1ul == bM4_ADC2_ISR_EOCBF) && (u32VSSEL142 & BIT_MASK_05))
+ {
+ ADC2B_IrqHandler();
+ }
+ }
+ /* ADC unit.2 seq. A */
+ if (1ul == bM4_ADC2_AWDCR_AWDIEN)
+ {
+ if ((M4_ADC2->AWDSR0 & 0x1FFu) && (u32VSSEL142 & BIT_MASK_06))
+ {
+ ADC2ChCmp_IrqHandler();
+ }
+ }
+ /* ADC unit.2 seq. cmp */
+ if (1ul == bM4_ADC2_AWDCR_AWDIEN)
+ {
+ if ((M4_ADC2->AWDSR0 & 0x1FFu) && (u32VSSEL142 & BIT_MASK_07))
+ {
+ ADC2SeqCmp_IrqHandler();
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Int No.143 share IRQ handler
+ **
+ ******************************************************************************/
+void IRQ143_Handler(void)
+{
+ uint8_t RTIF = 0u;
+ uint8_t RTIE = 0u;
+ uint8_t ERRINT = 0u;
+ uint8_t TTCFG = 0u;
+ uint16_t NORINTST = 0u;
+ uint16_t NORINTSGEN = 0u;
+ uint16_t ERRINTST = 0u;
+ uint16_t ERRINTSGEN = 0u;
+
+ /* SDIO Ch.1 */
+ if (1ul == bM4_INTC_VSSEL143_VSEL2)
+ {
+ NORINTST = M4_SDIOC1->NORINTST;
+ NORINTSGEN = M4_SDIOC1->NORINTSGEN;
+ ERRINTST = M4_SDIOC1->ERRINTST;
+ ERRINTSGEN = M4_SDIOC1->ERRINTSGEN;
+
+ if ((NORINTST & NORINTSGEN & 0x1F7u) || (ERRINTST & ERRINTSGEN & 0x017Fu))
+ {
+ Sdio1_IrqHandler();
+ }
+ }
+
+ /* SDIO Ch.2 */
+ if (1ul == bM4_INTC_VSSEL143_VSEL5)
+ {
+ NORINTST = M4_SDIOC2->NORINTST;
+ NORINTSGEN = M4_SDIOC2->NORINTSGEN;
+ ERRINTST = M4_SDIOC2->ERRINTST;
+ ERRINTSGEN = M4_SDIOC2->ERRINTSGEN;
+
+ if ((NORINTST & NORINTSGEN & 0x1F7u) || (ERRINTST & ERRINTSGEN & 0x017Fu))
+ {
+ Sdio2_IrqHandler();
+ }
+ }
+
+ /* CAN */
+ if (1ul == bM4_INTC_VSSEL143_VSEL6)
+ {
+ RTIF = M4_CAN->RTIF;
+ RTIE = M4_CAN->RTIE;
+ ERRINT = M4_CAN->ERRINT;
+ TTCFG = M4_CAN->TTCFG;
+ if ( (TTCFG & BIT_MASK_05) || \
+ (RTIF & BIT_MASK_00) || \
+ (RTIF & RTIE & 0xFEu) || \
+ ((ERRINT & BIT_MASK_00) && (ERRINT & BIT_MASK_01)) || \
+ ((ERRINT & BIT_MASK_02) && (ERRINT & BIT_MASK_03)) || \
+ ((ERRINT & BIT_MASK_04) && (ERRINT & BIT_MASK_05)) || \
+ ((TTCFG & BIT_MASK_03) && (TTCFG & BIT_MASK_04)) || \
+ ((TTCFG & BIT_MASK_06) && (TTCFG & BIT_MASK_07)))
+ {
+ Can_IrqHandler();
+ }
+ }
+}
+
+#endif
+
+//@} // InterruptGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_keyscan.c b/lib/hc32f460/driver/src/hc32f460_keyscan.c new file mode 100644 index 00000000..5da482cd --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_keyscan.c @@ -0,0 +1,203 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_keyscan.c
+ **
+ ** A detailed description is available at
+ ** @link KeyscanGroup Keyscan module description @endlink
+ **
+ ** - 2018-10-17 CDT First version for Device Driver Library of keyscan.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_keyscan.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup KeyscanGroup
+ ******************************************************************************/
+//@{
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*! Parameter validity check for Hiz cycle */
+#define IS_VALID_HIZ_CLCYE(x) \
+( ((x) == Hiz4) || \
+ ((x) == Hiz8) || \
+ ((x) == Hiz16) || \
+ ((x) == Hiz32) || \
+ ((x) == Hiz64) || \
+ ((x) == Hiz256) || \
+ ((x) == Hiz512) || \
+ ((x) == Hiz1K))
+
+/*! Parameter validity check for Low cycle */
+#define IS_VALID_LOW_CLCYE(x) \
+( ((x) == Low8) || \
+ ((x) == Low16) || \
+ ((x) == Low32) || \
+ ((x) == Low64) || \
+ ((x) == Low128) || \
+ ((x) == Low256) || \
+ ((x) == Low512) || \
+ ((x) == Low1K) || \
+ ((x) == Low2K) || \
+ ((x) == Low4K) || \
+ ((x) == Low8K) || \
+ ((x) == Low16K) || \
+ ((x) == Low32K) || \
+ ((x) == Low64K) || \
+ ((x) == Low128K) || \
+ ((x) == Low256K) || \
+ ((x) == Low512K) || \
+ ((x) == Low1M) || \
+ ((x) == Low2M) || \
+ ((x) == Low4M) || \
+ ((x) == Low8M) || \
+ ((x) == Low16M))
+
+/*! Parameter validity check for scan clock */
+#define IS_VALID_SCAN_CLK(x) \
+( ((x) == KeyscanHclk) || \
+ ((x) == KeyscanLrc) || \
+ ((x) == KeyscanXtal32))
+
+/*! Parameter validity check for keyout selection */
+#define IS_VALID_KEY_OUT(x) \
+( ((x) == Keyout0To1) || \
+ ((x) == Keyout0To2) || \
+ ((x) == Keyout0To3) || \
+ ((x) == Keyout0To4) || \
+ ((x) == Keyout0To5) || \
+ ((x) == Keyout0To6) || \
+ ((x) == Keyout0To7))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief KEYSCAN initialization
+ **
+ ** \param [in] pstcKeyscanConfig KEYSCAN configure structure
+ **
+ ** \retval Ok KEYSCAN initialized
+ ** ErrorInvalidMode Uninitialized, cannot configure it properly
+ **
+ ******************************************************************************/
+en_result_t KEYSCAN_Init(const stc_keyscan_config_t *pstcKeyscanConfig)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_HIZ_CLCYE(pstcKeyscanConfig->enHizCycle));
+ DDL_ASSERT(IS_VALID_LOW_CLCYE(pstcKeyscanConfig->enLowCycle));
+ DDL_ASSERT(IS_VALID_SCAN_CLK(pstcKeyscanConfig->enKeyscanClk));
+ DDL_ASSERT(IS_VALID_KEY_OUT(pstcKeyscanConfig->enKeyoutSel));
+
+ /* cannot configure keyscan control register when running */
+ if (Set == M4_KEYSCAN->SER_f.SEN)
+ {
+ enRet = ErrorInvalidMode;
+ }
+ else
+ {
+ M4_KEYSCAN->SCR_f.T_HIZ = pstcKeyscanConfig->enHizCycle;
+ M4_KEYSCAN->SCR_f.T_LLEVEL = pstcKeyscanConfig->enLowCycle;
+ M4_KEYSCAN->SCR_f.CKSEL = pstcKeyscanConfig->enKeyscanClk;
+ M4_KEYSCAN->SCR_f.KEYOUTSEL = pstcKeyscanConfig->enKeyoutSel;
+ M4_KEYSCAN->SCR_f.KEYINSEL = pstcKeyscanConfig->u16KeyinSel;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief KEYSCAN de-initialization
+ **
+ ** \param None
+ **
+ ** \retval Ok KEYSCAN de-initialized
+ **
+ ******************************************************************************/
+en_result_t KEYSCAN_DeInit(void)
+{
+ M4_KEYSCAN->SER = 0ul;
+ M4_KEYSCAN->SCR = 0ul;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Start keyscan function
+ **
+ ** \param None
+ **
+ ** \retval Ok Keyscan function started
+ **
+ ******************************************************************************/
+en_result_t KEYSCAN_Start(void)
+{
+ M4_KEYSCAN->SER_f.SEN = Set;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Stop keyscan function
+ **
+ ** \param None
+ **
+ ** \retval Ok Keyscan function stopped
+ **
+ ******************************************************************************/
+en_result_t KEYSCAN_Stop(void)
+{
+ M4_KEYSCAN->SER_f.SEN = Reset;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Key column index
+ **
+ ** \param None
+ **
+ ** \retval uint8_t Index of KEYOUT
+ **
+ ******************************************************************************/
+uint8_t KEYSCAN_GetColIdx(void)
+{
+ return (uint8_t)(M4_KEYSCAN->SSR_f.INDEX);
+}
+
+//@} // KeyscanGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_mpu.c b/lib/hc32f460/driver/src/hc32f460_mpu.c new file mode 100644 index 00000000..118b0e95 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_mpu.c @@ -0,0 +1,1053 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_mpu.c
+ **
+ ** A detailed description is available at
+ ** @link MpuGroup MPU description @endlink
+ **
+ ** - 2018-10-20 CDT First version for Device Driver Library of MPU.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_mpu.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup MpuGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter valid check for MPU region number. */
+#define IS_VALID_MPU_REGION_NUM(x) \
+( (MpuRegionNum0 == (x)) || \
+ (MpuRegionNum1 == (x)) || \
+ (MpuRegionNum2 == (x)) || \
+ (MpuRegionNum3 == (x)) || \
+ (MpuRegionNum4 == (x)) || \
+ (MpuRegionNum5 == (x)) || \
+ (MpuRegionNum6 == (x)) || \
+ (MpuRegionNum7 == (x)) || \
+ (MpuRegionNum8 == (x)) || \
+ (MpuRegionNum9 == (x)) || \
+ (MpuRegionNum10 == (x)) || \
+ (MpuRegionNum11 == (x)) || \
+ (MpuRegionNum12 == (x)) || \
+ (MpuRegionNum13 == (x)) || \
+ (MpuRegionNum14 == (x)) || \
+ (MpuRegionNum15 == (x)))
+
+/*!< Parameter valid check for MPU region size. */
+#define IS_VALID_MPU_REGION_SIZE(x) \
+( (MpuRegionSize32Byte == (x)) || \
+ (MpuRegionSize64Byte == (x)) || \
+ (MpuRegionSize128Byte == (x)) || \
+ (MpuRegionSize256Byte == (x)) || \
+ (MpuRegionSize512Byte == (x)) || \
+ (MpuRegionSize1KByte == (x)) || \
+ (MpuRegionSize2KByte == (x)) || \
+ (MpuRegionSize4KByte == (x)) || \
+ (MpuRegionSize8KByte == (x)) || \
+ (MpuRegionSize16KByte == (x)) || \
+ (MpuRegionSize32KByte == (x)) || \
+ (MpuRegionSize64KByte == (x)) || \
+ (MpuRegionSize128KByte == (x)) || \
+ (MpuRegionSize256KByte == (x)) || \
+ (MpuRegionSize512KByte == (x)) || \
+ (MpuRegionSize1MByte == (x)) || \
+ (MpuRegionSize2MByte == (x)) || \
+ (MpuRegionSize4MByte == (x)) || \
+ (MpuRegionSize8MByte == (x)) || \
+ (MpuRegionSize16MByte == (x)) || \
+ (MpuRegionSize32MByte == (x)) || \
+ (MpuRegionSize64MByte == (x)) || \
+ (MpuRegionSize128MByte == (x)) || \
+ (MpuRegionSize256MByte == (x)) || \
+ (MpuRegionSize512MByte == (x)) || \
+ (MpuRegionSize1GByte == (x)) || \
+ (MpuRegionSize2GByte == (x)) || \
+ (MpuRegionSize4GByte == (x)))
+
+/*!< Parameter valid check for MPU region type. */
+#define IS_VALID_MPU_REGION_TYPE(x) \
+( (SMPU1Region == (x)) || \
+ (SMPU2Region == (x)) || \
+ (FMPURegion == (x)))
+
+/*!< Parameter valid check for MPU action. */
+#define IS_VALID_MPU_ACTION(x) \
+( (MpuTrigNmi == (x)) || \
+ (MpuTrigReset == (x)) || \
+ (MpuNoneAction == (x)) || \
+ (MpuTrigBusError == (x)))
+
+/******************************************************************************/
+/* MPU */
+/******************************************************************************/
+/*!< Get the RGD register address of the specified MPU region */
+#define MPU_RGDx(__REGION_NUM__) ((uint32_t)(&M4_MPU->RGD0) + ((uint32_t)(__REGION_NUM__)) * 4u)
+
+/*!< Get the RGCR register address of the specified MPU region */
+#define MPU_RGCRx(__REGION_NUM__) ((uint32_t)(&M4_MPU->RGCR0) + ((uint32_t)(__REGION_NUM__)) * 4u)
+
+/*!< MPU RGD register: RGADDR position */
+#define MPU_RGD_RGADDR_Pos (5u) /*!< MPU_RGD: RGADDR Position */
+
+/*!< MPU write protection key */
+#define MPU_WRITE_PROT_KEY (0x96A4ul)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Configure MPU protect region.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] pstcInitCfg Pointer to MPU protection region configuration structure
+ ** \arg the structure detail refer @ref stc_mpu_prot_region_init_t
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - pstcInitCfg == NULL
+ ** - pstcInitCfg->u32RegionBaseAddress is invalid
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t MPU_ProtRegionInit(en_mpu_region_num_t enRegionNum,
+ const stc_mpu_prot_region_init_t *pstcInitCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint32_t u32WriteProt = M4_MPU->WP;
+ stc_mpu_rgd_field_t *RGD_f = NULL;
+ stc_mpu_rgcr0_field_t *RGCR_f = NULL;
+
+ /* Check pointer parameters */
+ if (NULL != pstcInitCfg)
+ {
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+ DDL_ASSERT(IS_VALID_MPU_REGION_SIZE(pstcInitCfg->enRegionSize));
+ DDL_ASSERT(IS_VALID_MPU_ACTION(pstcInitCfg->stcSMPU1Permission.enAction));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU1Permission.enRegionEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU1Permission.enWriteEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU1Permission.enReadEnable));
+ DDL_ASSERT(IS_VALID_MPU_ACTION(pstcInitCfg->stcSMPU2Permission.enAction));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU2Permission.enRegionEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU2Permission.enWriteEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU2Permission.enReadEnable));
+ DDL_ASSERT(IS_VALID_MPU_ACTION(pstcInitCfg->stcFMPUPermission.enAction));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcFMPUPermission.enRegionEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcFMPUPermission.enWriteEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcFMPUPermission.enReadEnable));
+
+ /* Check base address and region size */
+ if (!(pstcInitCfg->u32RegionBaseAddress & (~ (0xFFFFFFFFUL << ((uint32_t)pstcInitCfg->enRegionSize + 1UL)))))
+ {
+ /* Disable write protection of MPU register */
+ M4_MPU->WP = (MPU_WRITE_PROT_KEY | 1ul);
+
+ /* Get RGD && RGCR register address */
+ RGD_f = (stc_mpu_rgd_field_t *)MPU_RGDx(enRegionNum);
+ RGCR_f = (stc_mpu_rgcr0_field_t *)MPU_RGCRx(enRegionNum);
+
+ /* Disable region protection function */
+ RGCR_f->FRG0E = (uint32_t)0ul;
+ RGCR_f->S1RG0E = (uint32_t)0ul;
+ RGCR_f->S2RG0E = (uint32_t)0ul;
+
+ /* Set region size */
+ RGD_f->MPURGSIZE = (uint32_t)(pstcInitCfg->enRegionSize);
+
+ /* Set region base address */
+ RGD_f->MPURGADDR = (pstcInitCfg->u32RegionBaseAddress >> MPU_RGD_RGADDR_Pos);
+
+ /* Set region FMPU */
+ RGCR_f->FRG0RP = (pstcInitCfg->stcFMPUPermission.enReadEnable) ? 0ul : 1ul;
+ RGCR_f->FRG0WP = (pstcInitCfg->stcFMPUPermission.enWriteEnable) ? 0ul : 1ul;
+ RGCR_f->FRG0E = (uint32_t)(pstcInitCfg->stcFMPUPermission.enRegionEnable);
+ M4_MPU->CR_f.FMPUACT = (uint32_t)(pstcInitCfg->stcFMPUPermission.enAction);
+
+ /* Set region SMPU1 */
+ RGCR_f->S1RG0RP = (pstcInitCfg->stcSMPU1Permission.enReadEnable) ? 0ul : 1ul;
+ RGCR_f->S1RG0WP = (pstcInitCfg->stcSMPU1Permission.enWriteEnable) ? 0ul : 1ul;
+ RGCR_f->S1RG0E = (uint32_t)(pstcInitCfg->stcSMPU1Permission.enRegionEnable);
+ M4_MPU->CR_f.SMPU1ACT = (uint32_t)(pstcInitCfg->stcSMPU1Permission.enAction);
+
+ /* Set region SMPU2 */
+ RGCR_f->S2RG0RP = (pstcInitCfg->stcSMPU2Permission.enReadEnable) ? 0ul : 1ul;
+ RGCR_f->S2RG0WP = (pstcInitCfg->stcSMPU2Permission.enWriteEnable) ? 0ul : 1ul;
+ RGCR_f->S2RG0E = (uint32_t)(pstcInitCfg->stcSMPU2Permission.enRegionEnable);
+ M4_MPU->CR_f.SMPU2ACT = (uint32_t)(pstcInitCfg->stcSMPU2Permission.enAction);
+
+ /* Recover write protection of MPU register */
+ M4_MPU->WP = (MPU_WRITE_PROT_KEY | u32WriteProt);
+ enRet = Ok;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configure MPU background region.
+ **
+ ** \param [in] pstcInitCfg Pointer to MPU background region configuration structure
+ ** \arg the structure detail refer @ref stc_mpu_bkgd_region_init_t
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - pstcInitCfg == NULL
+ ** - pstcInitCfg->u32RegionBaseAddress is invalid
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t MPU_BkgdRegionInit(const stc_mpu_bkgd_region_init_t *pstcInitCfg)
+{
+ uint32_t u32WriteProt = M4_MPU->WP;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check pointer parameters */
+ if (NULL != pstcInitCfg)
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU1BkgdPermission.enWriteEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU1BkgdPermission.enReadEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU2BkgdPermission.enWriteEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcSMPU2BkgdPermission.enReadEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcFMPUBkgdPermission.enWriteEnable));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->stcFMPUBkgdPermission.enReadEnable));
+
+ /* Disable write protection of MPU register */
+ M4_MPU->WP = (MPU_WRITE_PROT_KEY | 1ul);
+
+ /* Set SMPU1 */
+ M4_MPU->CR_f.SMPU1BWP = (pstcInitCfg->stcSMPU1BkgdPermission.enWriteEnable) ? 0ul : 1ul;
+ M4_MPU->CR_f.SMPU1BRP = (pstcInitCfg->stcSMPU1BkgdPermission.enReadEnable) ? 0ul : 1ul;
+
+ /* Set SMPU2 */
+ M4_MPU->CR_f.SMPU2BWP = (pstcInitCfg->stcSMPU2BkgdPermission.enWriteEnable) ? 0ul : 1ul;
+ M4_MPU->CR_f.SMPU2BRP = (pstcInitCfg->stcSMPU2BkgdPermission.enReadEnable) ? 0ul : 1ul;
+
+ /* Set FMPU */
+ M4_MPU->CR_f.FMPUBWP = (pstcInitCfg->stcFMPUBkgdPermission.enWriteEnable) ? 0ul : 1ul;
+ M4_MPU->CR_f.FMPUBRP = (pstcInitCfg->stcFMPUBkgdPermission.enReadEnable) ? 0ul : 1ul;
+
+ /* Recover write protection of MPU register */
+ M4_MPU->WP = (MPU_WRITE_PROT_KEY | u32WriteProt);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU size of the specified region.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] enRegionSize MPU region size
+ ** \arg This parameter can be a value of @ref en_mpu_region_size_t
+ **
+ ** \retval Ok Set successfully.
+ **
+ ******************************************************************************/
+en_result_t MPU_SetRegionSize(en_mpu_region_num_t enRegionNum,
+ en_mpu_region_size_t enRegionSize)
+{
+ stc_mpu_rgd_field_t *RGD_f = NULL;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+ DDL_ASSERT(IS_VALID_MPU_REGION_SIZE(enRegionSize));
+
+ RGD_f = (stc_mpu_rgd_field_t *)MPU_RGDx(enRegionNum);
+ RGD_f->MPURGSIZE = (uint32_t)enRegionSize;
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get MPU size of the specified region.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ **
+ ** \retval MPU size of the specified region.
+ **
+ ******************************************************************************/
+en_mpu_region_size_t MPU_GetRegionSize(en_mpu_region_num_t enRegionNum)
+{
+ stc_mpu_rgd_field_t *RGD_f = NULL;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+
+ RGD_f = (stc_mpu_rgd_field_t *)MPU_RGDx(enRegionNum);
+
+ return (en_mpu_region_size_t)(RGD_f->MPURGSIZE);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU base address of the specified region.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] u32RegionBaseAddr the specified base address
+ **
+ ** \retval Ok Set successfully.
+ **
+ ******************************************************************************/
+en_result_t MPU_SetRegionBaseAddress(en_mpu_region_num_t enRegionNum,
+ uint32_t u32RegionBaseAddr)
+{
+ stc_mpu_rgd_field_t *RGD_f = NULL;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+
+ RGD_f = (stc_mpu_rgd_field_t *)MPU_RGDx(enRegionNum);
+ RGD_f->MPURGADDR = (u32RegionBaseAddr >> MPU_RGD_RGADDR_Pos);
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get MPU base address of the specified region.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+s **
+ ** \retval MPU base address of the specified region.
+ **
+ ******************************************************************************/
+uint32_t MPU_GetRegionBaseAddress(en_mpu_region_num_t enRegionNum)
+{
+ stc_mpu_rgd_field_t *RGD_f = NULL;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+
+ RGD_f = (stc_mpu_rgd_field_t *)MPU_RGDx(enRegionNum);
+
+ return (RGD_f->MPURGADDR << MPU_RGD_RGADDR_Pos);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the action of the specified MPU region type.
+ **
+ ** \param [in] enMpuRegionType the specified region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ ** \param [in] enActionSel MPU action
+ ** \arg MpuNoneAction MPU don't action.
+ ** \arg MpuTrigBusError MPU trigger bus error
+ ** \arg MpuTrigNmi MPU trigger bus NMI interrupt
+ ** \arg MpuTrigReset MPU trigger reset
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - enActionSel is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_SetNoPermissionAcessAction(en_mpu_region_type_t enMpuRegionType,
+ en_mpu_action_sel_t enActionSel)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_MPU_ACTION(enActionSel));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ M4_MPU->CR_f.SMPU1ACT = (uint32_t)enActionSel;
+ break;
+ case SMPU2Region:
+ M4_MPU->CR_f.SMPU2ACT = (uint32_t)enActionSel;
+ break;
+ case FMPURegion:
+ M4_MPU->CR_f.FMPUACT = (uint32_t)enActionSel;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the action of the specified MPU region type.
+ **
+ ** \param [in] enMpuRegionType the specified region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ **
+ ** \retval MpuNoneAction MPU don't action.
+ ** \retval MpuTrigBusError MPU trigger bus error
+ ** \retval MpuTrigNmi MPU trigger bus NMI interrupt
+ ** \retval MpuTrigReset MPU trigger reset
+ **
+ ******************************************************************************/
+en_mpu_action_sel_t MPU_GetNoPermissionAcessAction(en_mpu_region_type_t enMpuRegionType)
+{
+ uint32_t u32ActionSel = 0u;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ u32ActionSel = M4_MPU->CR_f.SMPU1ACT;
+ break;
+ case SMPU2Region:
+ u32ActionSel = M4_MPU->CR_f.SMPU2ACT;
+ break;
+ case FMPURegion:
+ u32ActionSel = M4_MPU->CR_f.FMPUACT;
+ break;
+ default:
+ break;
+ }
+
+ return (en_mpu_action_sel_t)(u32ActionSel);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU function of the specified region and type.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] enMpuRegionType the specified region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ ** \param [in] enState MPU region state
+ ** \arg Enable Enable the specified MPU region function
+ ** \arg Disable Disable the specified MPU region function
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - enMpuRegionType is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_ProtRegionCmd(en_mpu_region_num_t enRegionNum,
+ en_mpu_region_type_t enMpuRegionType,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = Ok;
+ stc_mpu_rgcr0_field_t *RGCR_f = NULL;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ RGCR_f = (stc_mpu_rgcr0_field_t *)MPU_RGCRx(enRegionNum);
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ RGCR_f->S1RG0E = (uint32_t)enState;
+ break;
+ case SMPU2Region:
+ RGCR_f->S2RG0E = (uint32_t)enState;
+ break;
+ case FMPURegion:
+ RGCR_f->FRG0E = (uint32_t)enState;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU function of the specified region type.
+ **
+ ** \param [in] enMpuRegionType the specified region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ ** \param [in] enState MPU region state
+ ** \arg Enable Enable the specified type region function of MPU
+ ** \arg Disable Disable the specified type region function of MPU
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - enMpuRegionType is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_RegionTypeCmd(en_mpu_region_type_t enMpuRegionType,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ M4_MPU->CR_f.SMPU1E = (uint32_t)enState;
+ break;
+ case SMPU2Region:
+ M4_MPU->CR_f.SMPU2E = (uint32_t)enState;
+ break;
+ case FMPURegion:
+ M4_MPU->CR_f.FMPUE = (uint32_t)enState;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get MPU status
+ **
+ ** \param [in] enMpuRegionType the specified region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ **
+ ** \retval Set Flag is set.
+ ** \retval Reset Flag is reset or enMpuRegionType is invalid.
+ **
+ ******************************************************************************/
+en_flag_status_t MPU_GetStatus(en_mpu_region_type_t enMpuRegionType)
+{
+ uint32_t u32Flag = 0ul;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ u32Flag = M4_MPU->SR_f.SMPU1EAF;
+ break;
+ case SMPU2Region:
+ u32Flag = M4_MPU->SR_f.SMPU2EAF;
+ break;
+ case FMPURegion:
+ u32Flag = M4_MPU->SR_f.FMPUEAF;
+ break;
+ default:
+ break;
+ }
+
+ return (en_flag_status_t)(u32Flag);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear MPU status.
+ **
+ ** \param [in] enMpuRegionType the specified region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ **
+ ** \retval Ok Clear flag successfully.
+ ** \retval ErrorInvalidParameter enMpuRegionType is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_ClearStatus(en_mpu_region_type_t enMpuRegionType)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ M4_MPU->ECLR_f.SMPU1ECLR = 1u;
+ break;
+ case SMPU2Region:
+ M4_MPU->ECLR_f.SMPU2ECLR = 1u;
+ break;
+ case FMPURegion:
+ M4_MPU->ECLR_f.FMPUECLR = 1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU read permission of the specified protection region and enMpuRegionType.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ ** \param [in] enState MPU region state
+ ** \arg Enable Enable the specified MPU region read permission
+ ** \arg Disable Disable the specified MPU region read permission
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enMpuRegionType is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_SetProtRegionReadPermission(en_mpu_region_num_t enRegionNum,
+ en_mpu_region_type_t enMpuRegionType,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = Ok;
+ stc_mpu_rgcr0_field_t *RGCR_f = NULL;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ RGCR_f = (stc_mpu_rgcr0_field_t *)MPU_RGCRx(enRegionNum);
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ RGCR_f->S1RG0RP = (Enable == enState) ? 0ul : 1ul;
+ break;
+ case SMPU2Region:
+ RGCR_f->S2RG0RP = (Enable == enState) ? 0ul : 1ul;
+ break;
+ case FMPURegion:
+ RGCR_f->FRG0RP = (Enable == enState) ? 0ul : 1ul;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get MPU read permission of the specified protection region and enMpuRegionType.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ **
+ ** \retval Enable Enable the specified MPU region read permission
+ ** \retval Disable Disable the specified MPU region read permission
+ **
+ ******************************************************************************/
+en_functional_state_t MPU_GetProtRegionReadPermission(en_mpu_region_num_t enRegionNum,
+ en_mpu_region_type_t enMpuRegionType)
+{
+ uint32_t u32State = 0u;
+ stc_mpu_rgcr0_field_t *RGCR_f = NULL;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ RGCR_f = (stc_mpu_rgcr0_field_t *)MPU_RGCRx(enRegionNum);
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ u32State = RGCR_f->S1RG0RP;
+ break;
+ case SMPU2Region:
+ u32State = RGCR_f->S2RG0RP;
+ break;
+ case FMPURegion:
+ u32State = RGCR_f->FRG0RP;
+ break;
+ default:
+ break;
+ }
+
+ return (u32State ? Disable : Enable);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU write permission of the specified protection region and enMpuRegionType.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ ** \param [in] enState MPU region state
+ ** \arg Enable Enable the specified MPU region write permission
+ ** \arg Disable Disable the specified MPU region write permission
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enMpuRegionType is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_SetProtRegionWritePermission(en_mpu_region_num_t enRegionNum,
+ en_mpu_region_type_t enMpuRegionType,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = Ok;
+ stc_mpu_rgcr0_field_t *RGCR_f = NULL;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ RGCR_f = (stc_mpu_rgcr0_field_t *)MPU_RGCRx(enRegionNum);
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ RGCR_f->S1RG0WP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ case SMPU2Region:
+ RGCR_f->S2RG0WP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ case FMPURegion:
+ RGCR_f->FRG0WP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get MPU write permission of the specified protection region and enMpuRegionType.
+ **
+ ** \param [in] enRegionNum MPU region number
+ ** \arg This parameter can be a value of @ref en_mpu_region_num_t
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ **
+ ** \retval Enable Enable the specified MPU region read permission
+ ** \retval Disable Disable the specified MPU region read permission
+ **
+ ******************************************************************************/
+en_functional_state_t MPU_GetProtRegionWritePermission(en_mpu_region_num_t enRegionNum,
+ en_mpu_region_type_t enMpuRegionType)
+{
+ uint32_t u32State = 0u;
+ stc_mpu_rgcr0_field_t *RGCR_f = NULL;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_NUM(enRegionNum));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ RGCR_f = (stc_mpu_rgcr0_field_t *)MPU_RGCRx(enRegionNum);
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ u32State = RGCR_f->S1RG0WP;
+ break;
+ case SMPU2Region:
+ u32State = RGCR_f->S2RG0WP;
+ break;
+ case FMPURegion:
+ u32State = RGCR_f->FRG0WP;
+ break;
+ default:
+ break;
+ }
+
+ return (u32State ? Disable : Enable);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU read permission of the specified background region and enMpuRegionType.
+ **
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ ** \param [in] enState MPU region state
+ ** \arg Enable Enable the specified MPU region read permission
+ ** \arg Disable Disable the specified MPU region read permission
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enMpuRegionType is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_SetBkgdRegionReadPermission(en_mpu_region_type_t enMpuRegionType,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ M4_MPU->CR_f.SMPU1BRP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ case SMPU2Region:
+ M4_MPU->CR_f.SMPU2BRP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ case FMPURegion:
+ M4_MPU->CR_f.FMPUBRP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get MPU read permission of the specified background region and enMpuRegionType.
+ **
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ **
+ ** \retval Enable Enable the specified MPU region read permission
+ ** \retval Disable Disable the specified MPU region read permission
+ **
+ ******************************************************************************/
+en_functional_state_t MPU_GetBkgdRegionReadPermission(en_mpu_region_type_t enMpuRegionType)
+{
+ uint32_t u32State = 0u;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ u32State = M4_MPU->CR_f.SMPU1BRP;
+ break;
+ case SMPU2Region:
+ u32State = M4_MPU->CR_f.SMPU2BRP;
+ break;
+ case FMPURegion:
+ u32State = M4_MPU->CR_f.FMPUBRP;
+ break;
+ default:
+ break;
+ }
+
+ return (u32State ? Disable : Enable);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU write permission of the specified background region and enMpuRegionType.
+ **
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ ** \param [in] enState MPU region state
+ ** \arg Enable Enable the specified MPU region write permission
+ ** \arg Disable Disable the specified MPU region write permission
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter enMpuRegionType is invalid
+ **
+ ******************************************************************************/
+en_result_t MPU_SetBkgdRegionWritePermission(en_mpu_region_type_t enMpuRegionType,
+ en_functional_state_t enState)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ M4_MPU->CR_f.SMPU1BWP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ case SMPU2Region:
+ M4_MPU->CR_f.SMPU2BWP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ case FMPURegion:
+ M4_MPU->CR_f.FMPUBWP = ((Enable == enState) ? 0ul : 1ul);
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get MPU write permission of the specified background region and enMpuRegionType.
+ **
+ ** \param [in] enMpuRegionType MPU region type
+ ** \arg SMPU1Region System DMA_1 MPU
+ ** \arg SMPU2Region System DMA_2 MPU
+ ** \arg FMPURegion System USBFS_DMA MPU
+ **
+ ** \retval Enable Enable the specified MPU region read permission
+ ** \retval Disable Disable the specified MPU region read permission
+ **
+ ******************************************************************************/
+en_functional_state_t MPU_GetBkgdRegionWritePermission(en_mpu_region_type_t enMpuRegionType)
+{
+ uint32_t u32State = 0u;
+
+ DDL_ASSERT(IS_VALID_MPU_REGION_TYPE(enMpuRegionType));
+
+ switch (enMpuRegionType)
+ {
+ case SMPU1Region:
+ u32State = M4_MPU->CR_f.SMPU1BWP;
+ break;
+ case SMPU2Region:
+ u32State = M4_MPU->CR_f.SMPU2BWP;
+ break;
+ case FMPURegion:
+ u32State = M4_MPU->CR_f.FMPUBWP;
+ break;
+ default:
+ break;
+ }
+
+ return (u32State ? Disable : Enable);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set MPU function of the specified region and type.
+ **
+ ** \param [in] enState MPU write protection state
+ ** \arg Enable Enable the write protection function
+ ** \arg Disable Disable the write protection function
+ **
+ ** \retval Ok Set successfully.
+ **
+ ******************************************************************************/
+en_result_t MPU_WriteProtCmd(en_functional_state_t enState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ M4_MPU->WP = (MPU_WRITE_PROT_KEY | ((Enable == enState) ? 0ul : 1ul));
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable the specified IP Write/Read protection.
+ **
+ ** \param [in] u32ProtMode Ip protection mode
+ ** \arg AesReadProt AES read protection
+ ** \arg AesWriteProt AES write protection
+ ** \arg HashReadProt HASH read protection
+ ** \arg HashWriteProt HASH write protection
+ ** \arg TrngReadProt TRNG read protection
+ ** \arg TrngWriteProt TRNG write protection
+ ** \arg CrcReadProt CRC read protection
+ ** \arg CrcWriteProt CRC write protection
+ ** \arg FmcReadProt FMC read protection
+ ** \arg FmcWriteProt FMC write protection
+ ** \arg WdtReadProt WDT read protection
+ ** \arg WdtWriteProt WDT write protection
+ ** \arg SwdtReadProt WDT read protection
+ ** \arg SwdtWriteProt WDT write protection
+ ** \arg BksramReadProt BKSRAM read protection
+ ** \arg BksramWriteProt BKSRAM write protection
+ ** \arg RtcReadProt RTC read protection
+ ** \arg RtcWriteProt RTC write protection
+ ** \arg DmpuReadProt DMPU read protection
+ ** \arg DmpuWriteProt DMPU write protection
+ ** \arg SramcReadProt SRAMC read protection
+ ** \arg SramcWriteProt SRAMC write protection
+ ** \arg IntcReadProt INTC read protection
+ ** \arg IntcWriteProt INTC write protection
+ ** \arg SyscReadProt SYSC read protection
+ ** \arg SyscWriteProt SYSC write protection
+ ** \arg MstpWriteProt MSTP write protection
+ ** \arg MstpWriteProt MSTP write protection
+ ** \arg BusErrProt BUSERR write protection
+ ** \param [in] enState MPU IP protection state
+ ** \arg Enable Enable the IP protection function
+ ** \arg Disable Disable the IP protection function
+ **
+ ** \retval Ok Set successfully.
+ **
+ ******************************************************************************/
+en_result_t MPU_IpProtCmd(uint32_t u32ProtMode,
+ en_functional_state_t enState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if(Enable == enState)
+ {
+ M4_SYSREG->MPU_IPPR |= u32ProtMode;
+ }
+ else
+ {
+ M4_SYSREG->MPU_IPPR &= (~u32ProtMode);
+ }
+
+ return Ok;
+}
+
+//@} // MpuGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_ots.c b/lib/hc32f460/driver/src/hc32f460_ots.c new file mode 100644 index 00000000..569cdb94 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_ots.c @@ -0,0 +1,382 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_ots.c
+ **
+ ** A detailed description is available at
+ ** @link OtsGroup Ots description @endlink
+ **
+ ** - 2018-10-26 CDT First version for Device Driver Library of Ots.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_ots.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup OtsGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*! Parameter validity check for OTS auto off configuration value. */
+#define IS_OTS_AUTO_OFF(EN) \
+( ((EN) == OtsAutoOff_Disable) || \
+ ((EN) == OtsAutoOff_Enable))
+
+/*! Parameter validity check for OTS interrupt enable/disable. */
+#define IS_OTS_IE(IE) \
+( ((IE) == OtsInt_Disable) || \
+ ((IE) == OtsInt_Enable))
+
+/*! Parameter validity check for OTS clock selection configuration value. */
+#define IS_OTS_CLK_SEL(CLK) \
+( ((CLK) == OtsClkSel_Xtal) || \
+ ((CLK) == OtsClkSel_Hrc))
+
+/*! Parameter validity check for OTS trigger source event . */
+#define IS_OTS_TRIG_SRC_EVENT(x) \
+( (((x) >= EVT_PORT_EIRQ0) && ((x) <= EVT_PORT_EIRQ15)) || \
+ (((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
+ (((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
+ (((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
+ (((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
+ (((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
+ (((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
+ (((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
+ (((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
+ (((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
+ (((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
+ (((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
+ (((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
+ (((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
+ (((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
+ (((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
+ (((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
+ (((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
+ (((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
+ (((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
+ (((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
+ (((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
+ (((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
+ (((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
+ (((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
+ (((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
+ ((x) == EVT_WDT_REFUDF) || \
+ (((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
+ (((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
+ (((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)) || \
+ ((x) == EVT_MAX))
+
+/*! Parameter validity check for OTS common trigger. */
+#define IS_OTS_COM_TRIGGER(x) \
+( ((x) == OtsComTrigger_1) || \
+ ((x) == OtsComTrigger_2) || \
+ ((x) == OtsComTrigger_1_2))
+
+#define EXPERIMENT_COUNT ((uint8_t)10)
+
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+static float32_t m_f32SlopeK = 0.0f;
+static float32_t m_f32OffsetM = 0.0f;
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+ /**
+ *******************************************************************************
+ ** \brief Initializes the OTS.
+ **
+ ** \param [in] pstcInit See @ref stc_ots_init_t for details.
+ **
+ ** \retval Ok No error occurred.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t OTS_Init(const stc_ots_init_t *pstcInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != pstcInit)
+ {
+ DDL_ASSERT(IS_OTS_AUTO_OFF(pstcInit->enAutoOff));
+ DDL_ASSERT(IS_OTS_CLK_SEL(pstcInit->enClkSel));
+
+ /* Stop ots sampling. */
+ bM4_OTS_CTL_OTSST = 0u;
+ /* Disable OTS interrupt default. */
+ bM4_OTS_CTL_OTSIE = OtsInt_Disable;
+
+ bM4_OTS_CTL_TSSTP = pstcInit->enAutoOff;
+ bM4_OTS_CTL_OTSCK = pstcInit->enClkSel;
+ m_f32SlopeK = pstcInit->f32SlopeK;
+ m_f32OffsetM = pstcInit->f32OffsetM;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Deinitializes the TRNG.
+ **
+ ** \param None.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void OTS_DeInit(void)
+{
+ /* Stop ots sampling. */
+ bM4_OTS_CTL_OTSST = 0u;
+
+ /* Set the value of all registers to the reset value. */
+ M4_OTS->CTL = 0u;
+ M4_OTS->DR1 = 0u;
+ M4_OTS->DR2 = 0u;
+ M4_OTS->ECR = 0u;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get temperature via normal mode.
+ **
+ ** \param [out] pf32Temp The address to store the temperature value.
+ **
+ ** \param [in] u32Timeout Timeout value.
+ **
+ ** \retval Ok No error occurred.
+ ** \retval ErrorTimeout OTS works timeout.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t OTS_Polling(float32_t *pf32Temp, uint32_t u32Timeout)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (pf32Temp != NULL)
+ {
+ enRet = ErrorTimeout;
+
+ OTS_Start();
+ do
+ {
+ if (bM4_OTS_CTL_OTSST == 0ul)
+ {
+ *pf32Temp = OTS_CalculateTemp();
+ enRet = Ok;
+ break;
+ }
+ } while (u32Timeout-- != 0ul);
+ OTS_Stop();
+ }
+
+ return enRet;
+}
+/**
+ *******************************************************************************
+ ** \brief Enable or disable OTS interrupt.
+ **
+ ** \param [in] enState Enable or disable OTS interrupt.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void OTS_IntCmd(en_functional_state_t enState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ bM4_OTS_CTL_OTSIE = (uint32_t)enState;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set OTS AOS trigger source.
+ **
+ ** \param [in] enEvent See @ref en_event_src_t for details.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void OTS_SetTriggerSrc(en_event_src_t enEvent)
+{
+ uint32_t u32OtrTrg = M4_AOS->OTS_TRG;
+
+ DDL_ASSERT(IS_OTS_TRIG_SRC_EVENT(enEvent) && (EVT_OTS != enEvent));
+
+ u32OtrTrg &= ~0x1FFul;
+ u32OtrTrg |= enEvent;
+
+ M4_AOS->OTS_TRG = u32OtrTrg;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable OTS common trigger.
+ **
+ ** \param [in] enComTrigger OTS common trigger selection. See @ref en_ots_com_trigger_t for details.
+ **
+ ** \param [in] enState Enable or disable the specified common trigger.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void OTS_ComTriggerCmd(en_ots_com_trigger_t enComTrigger, en_functional_state_t enState)
+{
+ uint32_t u32ComTrig = enComTrigger;
+
+ DDL_ASSERT(IS_OTS_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ u32ComTrig <<= 30u;
+
+ if (enState == Enable)
+ {
+ M4_AOS->OTS_TRG |= u32ComTrig;
+ }
+ else
+ {
+ M4_AOS->OTS_TRG &= ~u32ComTrig;
+ }
+}
+
+/**
+*******************************************************************************
+** \brief OTS scaling experiment. If you want to get a more accurate temperature value,
+** you need to do a calibration experiment.
+**
+** \param [out] pu16Dr1 Address to store OTS data register 1.
+**
+** \param [out] pu16Dr2 Address to store OTS data register 2.
+**
+** \param [out] pu16Ecr Address to store OTS error compensation register.
+**
+** \param [out] pf32A Address to store parameter A(for calibration experiments).
+**
+** \param [in] u32Timeout Timeout value.
+**
+** \retval Ok No error occurred.
+** \retval ErrorTimeout OTS works timeout.
+** \retval ErrorInvalidParameter Parameter error.
+******************************************************************************/
+en_result_t OTS_ScalingExperiment(uint16_t *pu16Dr1, uint16_t *pu16Dr2, \
+ uint16_t *pu16Ecr, float32_t *pf32A, \
+ uint32_t u32Timeout)
+{
+ float32_t f32Dr1;
+ float32_t f32Dr2;
+ float32_t f32Ecr;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if ((NULL != pu16Dr1) && (NULL != pu16Dr2) && \
+ (NULL != pu16Ecr) && (NULL != pf32A))
+ {
+ enRet = ErrorTimeout;
+ OTS_Start();
+ do
+ {
+ if (bM4_OTS_CTL_OTSST == 0ul)
+ {
+ enRet = Ok;
+ break;
+ }
+ } while (u32Timeout-- != 0ul);
+ OTS_Stop();
+
+ if (enRet == Ok)
+ {
+ *pu16Dr1 = M4_OTS->DR1;
+ *pu16Dr2 = M4_OTS->DR2;
+
+ f32Dr1 = (float32_t)(*pu16Dr1);
+ f32Dr2 = (float32_t)(*pu16Dr2);
+
+ if (bM4_OTS_CTL_OTSCK == OtsClkSel_Hrc)
+ {
+ *pu16Ecr = M4_OTS->ECR;
+ f32Ecr = (float32_t)(*pu16Ecr);
+ }
+ else
+ {
+ *pu16Ecr = 1U;
+ f32Ecr = 1.0f;
+ }
+
+ if ((f32Dr1 != 0.f) && (f32Dr2 != 0.f) && (f32Ecr != 0.f))
+ {
+ *pf32A = ((1.0f / f32Dr1) - (1.0f / f32Dr2)) * f32Ecr;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+
+/**
+*******************************************************************************
+** \brief Calculate the value of temperature.
+**
+** \retval A float32_t type value of temperature value.
+******************************************************************************/
+float OTS_CalculateTemp(void)
+{
+ float32_t f32Ret = 0.0f;
+ uint16_t u16Dr1 = M4_OTS->DR1;
+ uint16_t u16Dr2 = M4_OTS->DR2;
+ uint16_t u16Ecr = M4_OTS->ECR;
+ float32_t f32Dr1 = (float32_t)u16Dr1;
+ float32_t f32Dr2 = (float32_t)u16Dr2;
+ float32_t f32Ecr = (float32_t)u16Ecr;
+
+ if (bM4_OTS_CTL_OTSCK == OtsClkSel_Xtal)
+ {
+ f32Ecr = 1.0f;
+ }
+
+ if ((f32Dr1 != 0.f) && (f32Dr2 != 0.f) && (f32Ecr != 0.f))
+ {
+ f32Ret = m_f32SlopeK * ((1.0f / f32Dr1) - (1.0f / f32Dr2)) * f32Ecr + m_f32OffsetM;
+ }
+
+ return f32Ret;
+}
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+//@} // OtsGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_pwc.c b/lib/hc32f460/driver/src/hc32f460_pwc.c new file mode 100644 index 00000000..d57c5341 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_pwc.c @@ -0,0 +1,2021 @@ +/******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_pwc.c
+ **
+ ** A detailed description is available at
+ ** @link PwcGroup PWC description @endlink
+ **
+ ** - 2018-10-28 CDT First version for Device Driver Library of PWC.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_pwc.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup PwcGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define ENABLE_FCG0_REG_WRITE() (M4_MSTP->FCG0PC = 0xa5a50001u)
+#define DISABLE_FCG0_REG_WRITE() (M4_MSTP->FCG0PC = 0xa5a50000u)
+
+#define ENABLE_PWR_REG0_WRITE() (M4_SYSREG->PWR_FPRC |= 0xa503u)
+#define DISABLE_PWR_REG0_WRITE() (M4_SYSREG->PWR_FPRC = (0xa500u | (M4_SYSREG->PWR_FPRC & (uint16_t)(~3u))))
+
+#define ENABLE_PWR_REG_WRITE() (M4_SYSREG->PWR_FPRC |= 0xa502u)
+#define DISABLE_PWR_REG_WRITE() (M4_SYSREG->PWR_FPRC = (0xa500u | (M4_SYSREG->PWR_FPRC & (uint16_t)(~2u))))
+
+#define ENABLE_PVD_REG_WRITE() (M4_SYSREG->PWR_FPRC |= 0xa508u)
+#define DISABLE_PVD_REG_WRITE() (M4_SYSREG->PWR_FPRC = (0xa500u | (M4_SYSREG->PWR_FPRC & (uint16_t)(~8u))))
+
+/*! Parameter validity check for wake up event. */
+#define IS_PWC_WKUP_EVENT(evt) ((0x00u) != ((evt) & (0xFF)))
+
+/*! Parameter validity check for wake up event. */
+#define IS_PWC_WKUP2_EVENT(evt) ((0x00u) != ((evt) & (0xB7)))
+
+#define IS_PWC_WKUP_EDGE_EVENT(evt) ((0x00u) != ((evt) & (0x7F)))
+
+/*! Parameter validity check for wake up flag. */
+#define IS_PWC_WKUP0_FLAG(flag) ((0x00u) != ((flag) & (0x7F)))
+
+/*! Parameter validity check for wake up flag. */
+#define IS_PWC_WKUP1_FLAG(flag) ((0x07u) != ((flag) & (0xB8)))
+
+/*! Parameter validity check for power down mode. */
+#define IS_PWC_PWR_DOWN_MODE(md) \
+( ((md) == PowerDownMd1) || \
+ ((md) == PowerDownMd2) || \
+ ((md) == PowerDownMd3) || \
+ ((md) == PowerDownMd4))
+
+/*! Parameter validity check for power down wake_up time control. */
+#define IS_PWC_PWR_DOWN_WKUP_TIM(x) \
+( ((x) == Vcap01) || \
+ ((x) == Vcap0047))
+
+/*! Parameter validity check for IO retain state while power down. */
+#define IS_PWC_PWR_DWON_IO_STATE(x) \
+( ((x) == IoPwrDownRetain) || \
+ ((x) == IoPwrRstRetain) || \
+ ((x) == IoHighImp))
+
+/*! Parameter validity check for driver ability while enter stop mode. */
+#define IS_PWC_STP_DRIVER_ABILITY(x) \
+( ((x) == StopHighspeed) || \
+ ((x) == StopUlowspeed))
+
+/*! Parameter validity check for driver ability. */
+#define IS_PWC_DRIVER_ABILITY(x) \
+( ((x) == Ulowspeed) || \
+ ((x) == HighSpeed))
+
+/*! Parameter validity check for dynamic voltage. */
+#define IS_PWC_DYNAMIC_VOLTAGE(val) \
+( ((val) == RunUHighspeed) || \
+ ((val) == RunUlowspeed) || \
+ ((val) == RunHighspeed))
+
+/*! Parameter validity check for wake_up edge. */
+#define IS_PWC_EDGE_SEL(edg) \
+( ((edg) == EdgeFalling) || \
+ ((edg) == EdgeRising))
+
+/*! Parameter validity check for peripheral in fcg0. */
+#define IS_PWC_FCG0_PERIPH(per) \
+( (((per) & (0x700C3AEEu)) == (0x00u)) && \
+ ((0x00u) != (per)))
+
+/*! Parameter validity check for peripheral in fcg1. */
+#define IS_PWC_FCG1_PERIPH(per) \
+( (((per) & (0xF0F00286u)) == (0x00u)) && \
+ ((0x00u) != (per)))
+
+/*! Parameter validity check for peripheral in fcg2. */
+#define IS_PWC_FCG2_PERIPH(per) \
+( (((per) & (0xFFF87800u)) == (0x00u)) && \
+ ((0x00u) != (per)))
+
+/*! Parameter validity check for peripheral in fcg3. */
+#define IS_PWC_FCG3_PERIPH(per) \
+( (((per) & (0xFFFFEEECu)) == (0x00u)) && \
+ ((0x00u) != (per)))
+
+/*! Parameter validity check for clock value while stop mode mode. */
+#define IS_PWC_STOP_MODE_CLK(clk) \
+( ((clk) == ClkFix) || \
+ ((clk) == ClkMrc))
+
+/*! Parameter validity check for flash mode while stop mode mode. */
+#define IS_PWC_STOP_MODE_FLASH(x) \
+( ((x) == Wait) || \
+ ((x) == NotWait))
+
+/*! Parameter validity check for wake_up timer over flag. */
+#define IS_PWC_WKTMOVER_FLAG(flag) \
+( ((flag) == UnEqual) || \
+ ((flag) == Equal))
+
+/*! Parameter validity check for ram operate mode. */
+#define IS_PWC_RAM_OP_MD(x) \
+( ((x) == HighSpeedMd) || \
+ ((x) == UlowSpeedMd))
+
+/*! Parameter validity check for wake_up timer clock. */
+#define IS_PWC_WKTM_CLK(clk) \
+( ((clk) == Wk64hz) || \
+ ((clk) == WkXtal32) || \
+ ((clk) == WkLrc))
+
+
+/*! Parameter validity check for handle of pvd. */
+#define IS_PWC_PVD_MD(x) \
+( ((x) == PvdInt) || \
+ ((x) == PvdReset))
+
+
+/*! Parameter validity check for pvd1 level. */
+#define IS_PWC_PVD_FILTER_CLK(clk) \
+( ((clk) == PvdLrc025) || \
+ ((clk) == PvdLrc05) || \
+ ((clk) == PvdLrc1) || \
+ ((clk) == PvdLrc2))
+
+/*! Parameter validity check for pvd2 level. */
+#define IS_PWC_PVD2_LEVEL(lvl) \
+( ((lvl) == Pvd2Level0) || \
+ ((lvl) == Pvd2Level1) || \
+ ((lvl) == Pvd2Level2) || \
+ ((lvl) == Pvd2Level3) || \
+ ((lvl) == Pvd2Level4) || \
+ ((lvl) == Pvd2Level5) || \
+ ((lvl) == Pvd2Level6) || \
+ ((lvl) == Pvd2Level7))
+
+/*! Parameter validity check for pvd1 level. */
+#define IS_PWC_PVD1_LEVEL(lvl) \
+( ((lvl) == Pvd1Level0) || \
+ ((lvl) == Pvd1Level1) || \
+ ((lvl) == Pvd1Level2) || \
+ ((lvl) == Pvd1Level3) || \
+ ((lvl) == Pvd1Level4) || \
+ ((lvl) == Pvd1Level5) || \
+ ((lvl) == Pvd1Level6) || \
+ ((lvl) == Pvd1Level7))
+
+/*! Parameter validity check for pvd interrupt. */
+#define IS_PWC_PVD_INT_SEL(x) \
+( ((x) == NonMskInt) || \
+ ((x) == MskInt))
+
+/*! Parameter validity check for valid wakeup source from stop mode. */
+#define IS_VALID_WKUP_SRC(x) \
+( ((x) == INT_USART1_WUPI) || \
+ ((x) == INT_TMR01_GCMA) || \
+ ((x) == INT_RTC_ALM) || \
+ ((x) == INT_RTC_PRD) || \
+ ((x) == INT_WKTM_PRD) || \
+ ((x) == INT_ACMP1) || \
+ ((x) == INT_PVD_PVD1) || \
+ ((x) == INT_PVD_PVD2) || \
+ ((x) == INT_SWDT_REFUDF) || \
+ ((x) == INT_PORT_EIRQ0) || \
+ ((x) == INT_PORT_EIRQ1) || \
+ ((x) == INT_PORT_EIRQ2) || \
+ ((x) == INT_PORT_EIRQ3) || \
+ ((x) == INT_PORT_EIRQ4) || \
+ ((x) == INT_PORT_EIRQ5) || \
+ ((x) == INT_PORT_EIRQ6) || \
+ ((x) == INT_PORT_EIRQ7) || \
+ ((x) == INT_PORT_EIRQ8) || \
+ ((x) == INT_PORT_EIRQ9) || \
+ ((x) == INT_PORT_EIRQ10) || \
+ ((x) == INT_PORT_EIRQ11) || \
+ ((x) == INT_PORT_EIRQ12) || \
+ ((x) == INT_PORT_EIRQ13) || \
+ ((x) == INT_PORT_EIRQ14) || \
+ ((x) == INT_PORT_EIRQ15))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+uint32_t NVIC_ISER_BAK[5];
+uint8_t u8HrcState = 0u;
+uint8_t u8MrcState = 0u;
+uint8_t u8WkupIntCnt = 0u;
+uint8_t u8StopFlag = 0u;
+uint8_t u8SysClkSrc = 1u;
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief The power mode configuration.
+ **
+ ** \param [in] pstcPwrMdCfg The power mode configuration.
+ ** \arg enPwrDownMd The power down mode.
+ ** \arg enRLdo Enable or disable RLDO.
+ ** \arg enRetSram Enable or disable RetSram.
+ ** \arg enIoRetain The IO state while power down.
+ ** \arg enPwrDWkupTm The wake_up timer while power down.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_PowerModeCfg(const stc_pwc_pwr_mode_cfg_t* pstcPwrMdCfg)
+{
+ DDL_ASSERT(IS_PWC_PWR_DOWN_MODE(pstcPwrMdCfg->enPwrDownMd ));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPwrMdCfg->enRLdo));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPwrMdCfg->enRetSram));
+ DDL_ASSERT(IS_PWC_PWR_DWON_IO_STATE(pstcPwrMdCfg->enIoRetain));
+ DDL_ASSERT(IS_PWC_PWR_DOWN_WKUP_TIM(pstcPwrMdCfg->enPwrDWkupTm));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_PWRC0 = (pstcPwrMdCfg->enPwrDownMd |
+ (uint8_t)(((Enable == pstcPwrMdCfg->enRLdo) ? 0u : 1u) << 2u) |
+ (uint8_t)(((Enable == pstcPwrMdCfg->enRetSram) ? 0u : 1u) << 3u) |
+ (pstcPwrMdCfg->enIoRetain << 4u));
+
+ M4_SYSREG->PWR_PWRC3 = (pstcPwrMdCfg->enPwrDWkupTm | (0x03)) << 2u;
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enter power down mode.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note This function should be put ram
+ **
+ ******************************************************************************/
+__RAM_FUNC void PWC_EnterPowerDownMd(void)
+{
+ ENABLE_PVD_REG_WRITE();
+
+ /* Reset PVD1IRS & PVD2IRS */
+ M4_SYSREG->PWR_PVDCR1 &= 0xddu;
+
+ DISABLE_PVD_REG_WRITE();
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_STPMCR_f.STOP = 1u;
+
+ __disable_irq();
+ M4_SYSREG->PWR_PWRC0_f.PWDN = 1u;
+ for(uint8_t i = 0u; i < 10u; i++)
+ {
+ __NOP();
+ }
+ __enable_irq();
+
+ DISABLE_PWR_REG_WRITE();
+
+ __WFI();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the power down wake up event.
+ **
+ ** \param [in] u32Wkup0Event The wake_up event in PDWKEN0.
+ ** \arg PWC_PDWKEN0_WKUP00 Wake_up 0_0 event
+ ** \arg PWC_PDWKEN0_WKUP01 Wake_up 0_1 event
+ ** \arg PWC_PDWKEN0_WKUP02 Wake_up 0_2 event
+ ** \arg PWC_PDWKEN0_WKUP03 Wake_up 0_3 event
+ ** \arg PWC_PDWKEN0_WKUP10 Wake_up 1_0 event
+ ** \arg PWC_PDWKEN0_WKUP11 Wake_up 1_1 event
+ ** \arg PWC_PDWKEN0_WKUP12 Wake_up 1_2 event
+ ** \arg PWC_PDWKEN0_WKUP13 Wake_up 1_3 event
+ **
+ ** \param [in] enNewState The new state of the wake_up event.
+ ** \arg Enable Enable wake_up event.
+ ** \arg Disable Disable wake_up event.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_PdWakeup0Cmd(uint32_t u32Wkup0Event, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_PWC_WKUP_EVENT(u32Wkup0Event));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG_WRITE();
+
+ if(Enable == enNewState)
+ {
+ M4_SYSREG->PWR_PDWKE0 |= (uint8_t)u32Wkup0Event;
+ }
+ else
+ {
+ M4_SYSREG->PWR_PDWKE0 &= (uint8_t)(~u32Wkup0Event);
+ }
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the power down wake up event.
+ **
+ ** \param [in] u32Wkup1Event The wake_up event in PDWKEN0.
+ ** \arg PWC_PDWKEN1_WKUP20 Wake_up 2_0 event
+ ** \arg PWC_PDWKEN1_WKUP21 Wake_up 2_1 event
+ ** \arg PWC_PDWKEN1_WKUP22 Wake_up 2_2 event
+ ** \arg PWC_PDWKEN1_WKUP23 Wake_up 2_3 event
+ ** \arg PWC_PDWKEN1_WKUP30 Wake_up 3_0 event
+ ** \arg PWC_PDWKEN1_WKUP31 Wake_up 3_1 event
+ ** \arg PWC_PDWKEN1_WKUP32 Wake_up 3_2 event
+ ** \arg PWC_PDWKEN1_WKUP33 Wake_up 3_3 event
+ **
+ ** \param [in] enNewState The new state of the wake_up event.
+ ** \arg Enable Enable wake_up event.
+ ** \arg Disable Disable wake_up event.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_PdWakeup1Cmd(uint32_t u32Wkup1Event, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_PWC_WKUP_EVENT(u32Wkup1Event));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG_WRITE();
+
+ if(Enable == enNewState)
+ {
+ M4_SYSREG->PWR_PDWKE1 |= (uint8_t)u32Wkup1Event;
+ }
+ else
+ {
+ M4_SYSREG->PWR_PDWKE1 &= (uint8_t)(~u32Wkup1Event);
+ }
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the power down wake up event.
+ **
+ ** \param [in] u32Wkup2Event The wake_up event in PDWKEN0.
+ ** \arg PWC_PDWKEN2_PVD1 Wake_up PVD1 event
+ ** \arg PWC_PDWKEN2_PVD2 Wake_up PVD2 event
+ ** \arg PWC_PDWKEN2_NMI Wake_up NMI event
+ ** \arg PWC_PDWKEN2_RTCPRD Wake_up RTCPRD event
+ ** \arg PWC_PDWKEN2_RTCAL Wake_up RTCAL event
+ ** \arg PWC_PDWKEN2_WKTM Wake_up WKTM event
+ **
+ ** \param [in] enNewState The new state of the wake_up event.
+ ** \arg Enable Enable wake_up event.
+ ** \arg Disable Disable wake_up event.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_PdWakeup2Cmd(uint32_t u32Wkup2Event, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_PWC_WKUP2_EVENT(u32Wkup2Event));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG_WRITE();
+
+ if(Enable == enNewState)
+ {
+ M4_SYSREG->PWR_PDWKE2 |= (uint8_t)u32Wkup2Event;
+ }
+ else
+ {
+ M4_SYSREG->PWR_PDWKE2 &= (uint8_t)(~u32Wkup2Event);
+ }
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configure the power down wake up event edge.
+ **
+ ** \param [in] u8WkupEvent The wake_up event in PDWKEN0.
+ ** \arg PWC_PDWKUP_EDGE_WKP0 Wake_up WKP0 event
+ ** \arg PWC_PDWKUP_EDGE_WKP1 Wake_up WKP1 event
+ ** \arg PWC_PDWKUP_EDGE_WKP2 Wake_up WKP2 event
+ ** \arg PWC_PDWKUP_EDGE_WKP3 Wake_up WKP3 event
+ ** \arg PWC_PDWKUP_EDGE_PVD1 Wake_up PVD1 event
+ ** \arg PWC_PDWKUP_EDGE_PVD2 Wake_up PVD2 event
+ ** \arg PWC_PDWKUP_EDGE_NMI Wake_up NMI event
+ **
+ ** \param [in] enEdge The wake_up event edge select.
+ ** \arg EdgeRising Wake_up event edge rising.
+ ** \arg EdgeFalling Wake_up event edge falling.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_PdWakeupEvtEdgeCfg(uint8_t u8WkupEvent, en_pwc_edge_sel_t enEdge)
+{
+ DDL_ASSERT(IS_PWC_WKUP_EDGE_EVENT(u8WkupEvent));
+ DDL_ASSERT(IS_PWC_EDGE_SEL(enEdge));
+
+ ENABLE_PWR_REG_WRITE();
+
+ if(EdgeRising == enEdge)
+ {
+ M4_SYSREG->PWR_PDWKES |= (uint8_t)u8WkupEvent;
+ }
+ else
+ {
+ M4_SYSREG->PWR_PDWKES &= (uint8_t)(~u8WkupEvent);
+ }
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get wake_up event in PDWKF0 flag.
+ **
+ ** \param [in] u8WkupFlag The wake_up event in PDWKF0.
+ ** \arg PWC_PTWK0_WKUPFLAG Ptwk0 wake_up flag
+ ** \arg PWC_PTWK1_WKUPFLAG Ptwk1 wake_up flag
+ ** \arg PWC_PTWK2_WKUPFLAG Ptwk2 wake_up flag
+ ** \arg PWC_PTWK3_WKUPFLAG Ptwk3 wake_up flag
+ ** \arg PWC_PVD1_WKUPFLAG Pvd1 wake_up flag
+ ** \arg PWC_PVD2_WKUPFLAG Pvd2 wake_up flag
+ ** \arg PWC_NMI_WKUPFLAG Nmi wake_up flag
+ **
+ ** \retval en_flag_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t PWC_GetWakeup0Flag(uint8_t u8WkupFlag)
+{
+ uint8_t u8flag;
+ DDL_ASSERT(IS_PWC_WKUP0_FLAG(u8WkupFlag));
+
+ u8flag = (M4_SYSREG->PWR_PDWKF0 & u8WkupFlag);
+
+ return ((0u == u8flag) ? Reset : Set);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get wake_up event in PDWKF1 flag.
+ **
+ ** \param [in] u8WkupFlag The wake_up event in PDWKF1.
+ ** \arg PWC_RTCPRD_WKUPFALG Rtcprd wake_up flag
+ ** \arg PWC_RTCAL_WKUPFLAG Rtcal wake_up flag
+ ** \arg PWC_WKTM_WKUPFLAG Wktm wake_up flag
+ **
+ ** \retval en_flag_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t PWC_GetWakeup1Flag(uint8_t u8WkupFlag)
+{
+ uint8_t u8flag;
+ DDL_ASSERT(IS_PWC_WKUP1_FLAG(u8WkupFlag));
+
+ u8flag = (M4_SYSREG->PWR_PDWKF1 & u8WkupFlag);
+
+ return ((0u == u8flag) ? Reset : Set);
+}
+
+/**
+ *******************************************************************************
+ ** \brief clear wake_up event in PDWKF0 flag.
+ **
+ ** \param [in] u8WkupFlag The wake_up event in PDWKF0.
+ ** \arg PWC_PTWK0_WKUPFLAG Ptwk0 wake_up flag
+ ** \arg PWC_PTWK1_WKUPFLAG Ptwk1 wake_up flag
+ ** \arg PWC_PTWK2_WKUPFLAG Ptwk2 wake_up flag
+ ** \arg PWC_PTWK3_WKUPFLAG Ptwk3 wake_up flag
+ ** \arg PWC_PVD1_WKUPFLAG Pvd1 wake_up flag
+ ** \arg PWC_PVD2_WKUPFLAG Pvd2 wake_up flag
+ ** \arg PWC_NMI_WKUPFLAG Nmi wake_up flag
+ **
+ ** \retval en_flag_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_ClearWakeup0Flag(uint8_t u8WkupFlag)
+{
+ DDL_ASSERT(IS_PWC_WKUP0_FLAG(u8WkupFlag));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_PDWKF0 &= (uint8_t)(~u8WkupFlag);
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief clear wake_up event in PDWKF1 flag.
+ **
+ ** \param [in] u8WkupFlag The wake_up event in PDWKF1.
+ ** \arg PWC_RTCPRD_WKUPFALG Rtcprd wake_up flag
+ ** \arg PWC_RTCAL_WKUPFLAG Rtcal wake_up flag
+ ** \arg PWC_WKTM_WKUPFLAG Wktm wake_up flag
+ **
+ ** \retval en_flag_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_ClearWakeup1Flag(uint8_t u8WkupFlag)
+{
+ DDL_ASSERT(IS_PWC_WKUP1_FLAG(u8WkupFlag));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_PDWKF1 &= (uint8_t)(~u8WkupFlag);
+
+ DISABLE_PWR_REG_WRITE();
+}
+/**
+ *******************************************************************************
+ ** \brief Enable or disable power monitor .
+ **
+ ** \param [in] enNewState The power monitor state.
+ ** \arg Enable Enable power monitor.
+ ** \arg Disable Disable power monitor.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_PwrMonitorCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_PWCMR_f.ADBUFE = ((Enable == enNewState) ? 1u : 0u);
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the FCG0 peripheral clock.
+ **
+ ** \note After reset,the peripheral clock is disabled and the application
+ ** software has to enable this clock before using it.
+ **
+ ** \param [in] u32Fcg0Periph The peripheral in FCG0.
+ ** \arg PWC_FCG0_PERIPH_SRAMH RAMHS clock
+ ** \arg PWC_FCG0_PERIPH_SRAM12 RAM0 clock
+ ** \arg PWC_FCG0_PERIPH_SRAM3 ECCRAM clock
+ ** \arg PWC_FCG0_PERIPH_SRAMRET RetRAM clock
+ ** \arg PWC_FCG0_PERIPH_DMA1 DMA1 clock
+ ** \arg PWC_FCG0_PERIPH_DMA2 DMA2 clock
+ ** \arg PWC_FCG0_PERIPH_FCM FCM clock
+ ** \arg PWC_FCG0_PERIPH_AOS PTDIS clock
+ ** \arg PWC_FCG0_PERIPH_AES AES clock
+ ** \arg PWC_FCG0_PERIPH_HASH HASH clock
+ ** \arg PWC_FCG0_PERIPH_TRNG TRNG clock
+ ** \arg PWC_FCG0_PERIPH_CRC CRC clock
+ ** \arg PWC_FCG0_PERIPH_DCU1 DCU1 clock
+ ** \arg PWC_FCG0_PERIPH_DCU2 DCU2 clock
+ ** \arg PWC_FCG0_PERIPH_DCU3 DCU3 clock
+ ** \arg PWC_FCG0_PERIPH_DCU4 DCU4 clock
+ ** \arg PWC_FCG0_PERIPH_KEY KEY clock
+
+ ** \param [in] enNewState The new state of the clock output.
+ ** \arg Enable Enable clock output.
+ ** \arg Disable Disable clock output.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_Fcg0PeriphClockCmd(uint32_t u32Fcg0Periph, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_PWC_FCG0_PERIPH(u32Fcg0Periph));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_FCG0_REG_WRITE();
+
+ if(Enable == enNewState)
+ {
+ M4_MSTP->FCG0 &= ~u32Fcg0Periph;
+ }
+ else
+ {
+ M4_MSTP->FCG0 |= u32Fcg0Periph;
+ }
+
+ DISABLE_FCG0_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the FCG1 peripheral clock.
+ **
+ ** \note After reset,the peripheral clock is disabled and the application
+ ** software has to enable this clock before using it.
+ **
+ ** \param [in] u32Fcg1Periph The peripheral in FCG1.
+ ** \arg PWC_FCG1_PERIPH_CAN CAN clock
+ ** \arg PWC_FCG1_PERIPH_QSPI QSPI clock
+ ** \arg PWC_FCG1_PERIPH_I2C1 I2C1 clock
+ ** \arg PWC_FCG1_PERIPH_I2C2 I2C2 clock
+ ** \arg PWC_FCG1_PERIPH_I2C3 I2C3 clock
+ ** \arg PWC_FCG1_PERIPH_USBFS USBFS clock
+ ** \arg PWC_FCG1_PERIPH_SDIOC1 SDIOC1 clock
+ ** \arg PWC_FCG1_PERIPH_SDIOC2 SDIOC2 clock
+ ** \arg PWC_FCG1_PERIPH_I2S1 I2S1 clock
+ ** \arg PWC_FCG1_PERIPH_I2S2 I2S2 clock
+ ** \arg PWC_FCG1_PERIPH_I2S3 I2S3 clock
+ ** \arg PWC_FCG1_PERIPH_I2S4 I2S4 clock
+ ** \arg PWC_FCG1_PERIPH_SPI1 SPI1 clock
+ ** \arg PWC_FCG1_PERIPH_SPI2 SPI2 clock
+ ** \arg PWC_FCG1_PERIPH_SPI3 SPI3 clock
+ ** \arg PWC_FCG1_PERIPH_SPI4 SPI4 clock
+ ** \arg PWC_FCG1_PERIPH_USART1 USART1 clock
+ ** \arg PWC_FCG1_PERIPH_USART2 USART2 clock
+ ** \arg PWC_FCG1_PERIPH_USART3 USART3 clock
+ ** \arg PWC_FCG1_PERIPH_USART4 USART4 clock
+ **
+ ** \param [in] enNewState The new state of the clock output.
+ ** \arg Enable Enable clock output.
+ ** \arg Disable Disable clock output.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_Fcg1PeriphClockCmd(uint32_t u32Fcg1Periph, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_PWC_FCG1_PERIPH(u32Fcg1Periph));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(Enable == enNewState)
+ {
+ M4_MSTP->FCG1 &= ~u32Fcg1Periph;
+ }
+ else
+ {
+ M4_MSTP->FCG1 |= u32Fcg1Periph;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the FCG2 peripheral clock.
+ **
+ ** \note After reset,the peripheral clock is disabled and the application
+ ** software has to enable this clock before using it.
+ **
+ ** \param [in] u32Fcg2Periph The peripheral in FCG2.
+ ** \arg PWC_FCG2_PERIPH_TIM01 TIM01 clock
+ ** \arg PWC_FCG2_PERIPH_TIM02 TIM02 clock
+ ** \arg PWC_FCG2_PERIPH_TIMA1 TIMA1 clock
+ ** \arg PWC_FCG2_PERIPH_TIMA2 TIMA2 clock
+ ** \arg PWC_FCG2_PERIPH_TIMA3 TIMA3 clock
+ ** \arg PWC_FCG2_PERIPH_TIMA4 TIMA4 clock
+ ** \arg PWC_FCG2_PERIPH_TIMA5 TIMA5 clock
+ ** \arg PWC_FCG2_PERIPH_TIMA6 TIMA6 clock
+ ** \arg PWC_FCG2_PERIPH_TIM41 TIM41 clock
+ ** \arg PWC_FCG2_PERIPH_TIM42 TIM42 clock
+ ** \arg PWC_FCG2_PERIPH_TIM43 TIM43 clock
+ ** \arg PWC_FCG2_PERIPH_EMB EMB clock
+ ** \arg PWC_FCG2_PERIPH_TIM61 TIM61 clock
+ ** \arg PWC_FCG2_PERIPH_TIM62 TIM62 clock
+ ** \arg PWC_FCG2_PERIPH_TIM63 TIM63 clock
+
+ **
+ ** \param [in] enNewState The new state of the clock output.
+ ** \arg Enable Enable clock output.
+ ** \arg Disable Disable clock output.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_Fcg2PeriphClockCmd(uint32_t u32Fcg2Periph, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_PWC_FCG2_PERIPH(u32Fcg2Periph));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(Enable == enNewState)
+ {
+ M4_MSTP->FCG2 &= ~u32Fcg2Periph;
+ }
+ else
+ {
+ M4_MSTP->FCG2 |= u32Fcg2Periph;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the FCG3 peripheral clock.
+ **
+ ** \note After reset,the peripheral clock is disabled and the application
+ ** software has to enable this clock before using it.
+ **
+ ** \param [in] u32Fcg3Periph The peripheral in FCG3.
+ ** \arg PWC_FCG3_PERIPH_ADC1 ADC1 clock
+ ** \arg PWC_FCG3_PERIPH_ADC2 ADC2 clock
+ ** \arg PWC_FCG3_PERIPH_CMP CMP clock
+ ** \arg PWC_FCG3_PERIPH_OTS OTS clock
+ **
+ ** \param [in] enNewState The new state of the clock output.
+ ** \arg Enable Enable clock output.
+ ** \arg Disable Disable clock output.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_Fcg3PeriphClockCmd(uint32_t u32Fcg3Periph, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_PWC_FCG3_PERIPH(u32Fcg3Periph));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(Enable == enNewState)
+ {
+ M4_MSTP->FCG3 &= ~u32Fcg3Periph;
+ }
+ else
+ {
+ M4_MSTP->FCG3 |= u32Fcg3Periph;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief The stop mode configuration.
+ **
+ ** \param [in] pstcStpMdCfg Pointer to stop mode configuration structure.
+ ** \arg Enable Enable stop mode.
+ ** \arg Disable Disable stop mode.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_result_t PWC_StopModeCfg(const stc_pwc_stop_mode_cfg_t* pstcStpMdCfg)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_PWC_STOP_MODE_FLASH(pstcStpMdCfg->enStopFlash));
+ DDL_ASSERT(IS_PWC_STOP_MODE_CLK(pstcStpMdCfg->enStopClk));
+
+ ENABLE_PWR_REG0_WRITE();
+
+ M4_SYSREG->PWR_STPMCR = (pstcStpMdCfg->enStopFlash |
+ (pstcStpMdCfg->enStopClk << 1u) |
+ (1u << 14u));
+
+ /* if should close HRC & PLL while stop mode, please disable before modifying the register */
+ if(Disable == pstcStpMdCfg->enPll)
+ {
+ /* PLL is system clock */
+ if(5u == M4_SYSREG->CMU_CKSWR_f.CKSW)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ /* Disable PLL */
+ M4_SYSREG->CMU_PLLCR_f.MPLLOFF = 1u;
+ }
+ }
+
+ /* Hrc power should be enable. */
+ M4_SYSREG->PWR_PWRC1_f.VHRCSD = 0u;
+ M4_SYSREG->PWR_PWRC1_f.VPLLSD = ((Enable == pstcStpMdCfg->enPll) ? 0u : 1u);
+ M4_SYSREG->PWR_PWRC1_f.STPDAS = pstcStpMdCfg->enStpDrvAbi;
+
+ DISABLE_PWR_REG0_WRITE();
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable the power down wake up event.
+ **
+ ** \param [in] u32Wkup0Event The wake_up event in PDWKEN0.
+ ** \arg PWC_STOPWKUPEN_EIRQ0 EIRQ0 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ1 EIRQ1 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ2 EIRQ2 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ3 EIRQ3 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ4 EIRQ4 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ5 EIRQ5 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ6 EIRQ6 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ7 EIRQ7 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ8 EIRQ8 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ9 EIRQ9 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ10 EIRQ10 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ11 EIRQ11 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ12 EIRQ12 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ13 EIRQ13 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ14 EIRQ14 wake_up event
+ ** \arg PWC_STOPWKUPEN_EIRQ15 EIRQ15 wake_up event
+ ** \arg PWC_STOPWKUPEN_SWDT SWDT wake_up event
+ ** \arg PWC_STOPWKUPEN_VDU1 VDU1 wake_up event
+ ** \arg PWC_STOPWKUPEN_VDU2 VDU2 wake_up event
+ ** \arg PWC_STOPWKUPEN_CMPI0 CMPI0 wake_up event
+ ** \arg PWC_STOPWKUPEN_WKTM WKTM wake_up event
+ ** \arg PWC_STOPWKUPEN_RTCAL RTCAL wake_up event
+ ** \arg PWC_STOPWKUPEN_RTCPRD RTCPRD wake_up event
+ ** \arg PWC_STOPWKUPEN_TMR0 TMR0 wake_up event
+ ** \arg PWC_STOPWKUPEN_USARTRXD USARTRXD wake_up event
+ **
+ ** \param [in] enNewState The new state of the wake_up event.
+ ** \arg Enable Enable wake_up event.
+ ** \arg Disable Disable wake_up event.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_StopWkupCmd(uint32_t u32Wkup0Event, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ if(Enable == enNewState)
+ {
+ M4_INTC->WUPEN |= u32Wkup0Event;
+ }
+ else
+ {
+ M4_INTC->WUPEN &= ~u32Wkup0Event;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enter sleep mode.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void PWC_EnterSleepMd(void)
+{
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_STPMCR_f.STOP = 0u;
+ M4_SYSREG->PWR_PWRC0_f.PWDN = 0u;
+
+ DISABLE_PWR_REG_WRITE();
+
+ __WFI();
+}
+/**
+ *******************************************************************************
+ ** \brief Ram area power down commond.
+ **
+ ** \param [in] u32RamCtlBit The ram area contol.
+ ** \arg PWC_RAMPWRDOWN_SRAM1 Ram0(0x20000000-0x2000FFFF) power down control.
+ ** \arg PWC_RAMPWRDOWN_SRAM2 Ram1(0x20010000-0x2001FFFF) power down control.
+ ** \arg PWC_RAMPWRDOWN_SRAM3 Ram2(0x20020000-0x20026FFF) power down control.
+ ** \arg PWC_RAMPWRDOWN_SRAMH Ram3(0x1FFF8000-0x1FFFFFFF) power down control.
+ ** \arg PWC_RAMPWRDOWN_USBFS Usbfs power down control.
+ ** \arg PWC_RAMPWRDOWN_SDIOC0 Sdioc0 power down control.
+ ** \arg PWC_RAMPWRDOWN_SDIOC1 Sdioc1 power down control.
+ ** \arg PWC_RAMPWRDOWN_CAN Can power down control.
+ ** \arg PWC_RAMPWRDOWN_CACHE Cache power down control.
+ ** \arg PWC_RAMPWRDOWN_FULL Full.
+ **
+ ** \param [in] enNewState The new state of the Ram area.
+ ** \arg Enable Ten ram area run.
+ ** \arg Disable The ram area power down.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_RamPwrdownCmd(uint32_t u32RamCtlBit, en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG_WRITE();
+
+ if(Enable == enNewState)
+ {
+ M4_SYSREG->PWR_RAMPC0 &= ~u32RamCtlBit;
+ }
+ else
+ {
+ M4_SYSREG->PWR_RAMPC0 |= u32RamCtlBit;
+ }
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+void PWC_RamOpMdConfig(en_pwc_ram_op_md_t enRamOpMd)
+{
+ DDL_ASSERT(IS_PWC_RAM_OP_MD(enRamOpMd));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_RAMOPM = enRamOpMd;
+
+ DISABLE_PWR_REG_WRITE();
+}
+/**
+ *******************************************************************************
+ ** \brief Enable or disable XTAL/RTC/WKTM bias current.
+ **
+ ** \param [in] enNewState The XTAL/RTC/WKTM bias current state.
+ ** \arg Enable Enable XTAL/RTC/WKTM bias current.
+ ** \arg Disable Disable XTAL/RTC/WKTM bias current.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_Xtal32CsCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG0_WRITE();
+
+ M4_SYSREG->PWR_XTAL32CS_f.CSDIS = ((Enable == enNewState) ? 0u : 1u);
+
+ DISABLE_PWR_REG0_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief wake_up timer control.
+ **
+ ** \param [in] pstcWktmCtl The wake_up timer configuration.
+ ** \arg enWktmEn Enable or disable wake_up timer.
+ ** \arg enWkclk The wake_up timer clock.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_WktmControl(const stc_pwc_wktm_ctl_t* pstcWktmCtl)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcWktmCtl->enWktmEn));
+ DDL_ASSERT(IS_PWC_WKTM_CLK(pstcWktmCtl->enWkclk));
+ DDL_ASSERT(IS_PWC_WKTMOVER_FLAG(pstcWktmCtl->enWkOverFlag));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_WKTM->CR = ((pstcWktmCtl->u16WktmCmp & PWC_WKTMCMP_MSK) |
+ (pstcWktmCtl->enWkOverFlag << 12) |
+ (pstcWktmCtl->enWkclk << 13) |
+ (pstcWktmCtl->enWktmEn << 15));
+
+ DISABLE_PWR_REG_WRITE();
+}
+/**
+ *******************************************************************************
+ ** \brief The pvd configuration.
+ **
+ ** \param [in] pstcPvdCfg The pvd configuration.
+ ** \arg enPtwk0Edge Ptwk0 edge
+ ** \arg enPtwk1Edge Ptwk1 edge
+ ** \arg enPtwk2Edge Ptwk2 edge
+ ** \arg enPtwk3Edge Ptwk3 edge
+ ** \arg enPvd1Edge Pvd1 edge
+ ** \arg enPvd1Edge Pvd2 edge
+ ** \arg enNmiEdge Nmi edge
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_PvdCfg(const stc_pwc_pvd_cfg_t* pstcPvdCfg)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPvdCfg->stcPvd1Ctl.enPvdIREn));
+ DDL_ASSERT(IS_PWC_PVD_MD(pstcPvdCfg->stcPvd1Ctl.enPvdMode));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPvdCfg->stcPvd1Ctl.enPvdCmpOutEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPvdCfg->stcPvd2Ctl.enPvdIREn));
+ DDL_ASSERT(IS_PWC_PVD_MD(pstcPvdCfg->stcPvd2Ctl.enPvdMode));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPvdCfg->stcPvd2Ctl.enPvdCmpOutEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPvdCfg->enPvd1FilterEn));
+ DDL_ASSERT(IS_PWC_PVD_FILTER_CLK(pstcPvdCfg->enPvd1Filtclk));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPvdCfg->enPvd2FilterEn));
+ DDL_ASSERT(IS_PWC_PVD_FILTER_CLK(pstcPvdCfg->enPvd2Filtclk));
+ DDL_ASSERT(IS_PWC_PVD1_LEVEL(pstcPvdCfg->enPvd1Level));
+ DDL_ASSERT(IS_PWC_PVD2_LEVEL(pstcPvdCfg->enPvd2Level));
+ DDL_ASSERT(IS_PWC_PVD_INT_SEL(pstcPvdCfg->enPvd1Int));
+ DDL_ASSERT(IS_PWC_PVD_INT_SEL(pstcPvdCfg->enPvd2Int));
+
+ ENABLE_PVD_REG_WRITE();
+
+ /* Config Pvd control. */
+ M4_SYSREG->PWR_PVDCR1 = (pstcPvdCfg->stcPvd1Ctl.enPvdIREn |
+ (pstcPvdCfg->stcPvd1Ctl.enPvdMode << 1) |
+ (pstcPvdCfg->stcPvd1Ctl.enPvdCmpOutEn << 2) |
+ (pstcPvdCfg->stcPvd2Ctl.enPvdIREn<< 4) |
+ (pstcPvdCfg->stcPvd2Ctl.enPvdMode << 5) |
+ (pstcPvdCfg->stcPvd2Ctl.enPvdCmpOutEn << 6));
+ /* Set pvd filter sampling. */
+ M4_SYSREG->PWR_PVDFCR = (~(pstcPvdCfg->enPvd1FilterEn) |
+ (pstcPvdCfg->enPvd1Filtclk << 1) |
+ ((~pstcPvdCfg->enPvd2FilterEn) << 4) |
+ (pstcPvdCfg->enPvd2Filtclk << 5));
+ /* Set pvd level. */
+ M4_SYSREG->PWR_PVDLCR = (pstcPvdCfg->enPvd1Level |
+ (pstcPvdCfg->enPvd2Level << 4));
+ /* Set pvd interrupt(non_maskable or maskable). */
+ M4_SYSREG->PWR_PVDICR = (pstcPvdCfg->enPvd1Int |
+ (pstcPvdCfg->enPvd2Int << 4));
+
+ DISABLE_PVD_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable pvd1.
+ **
+ ** \param [in] enNewState The pvd1 state.
+ ** \arg Enable Enable pvd1.
+ ** \arg Disable Disable pvd1.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_Pvd1Cmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PVD_REG_WRITE();
+
+ M4_SYSREG->PWR_PVDCR0_f.PVD1EN = ((Enable == enNewState) ? 1u : 0u);
+
+ DISABLE_PVD_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable pvd2.
+ **
+ ** \param [in] enNewState The pvd2 state.
+ ** \arg Enable Enable pvd2.
+ ** \arg Disable Disable pvd2.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_Pvd2Cmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PVD_REG_WRITE();
+
+ M4_SYSREG->PWR_PVDCR0_f.PVD2EN = ((Enable == enNewState) ? 1u : 0u);
+
+ DISABLE_PVD_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable external vcc.
+ **
+ ** \param [in] enNewState The external vcc state.
+ ** \arg Enable Enable external vcc.
+ ** \arg Disable Disable external vcc.
+ **
+ ** \retval None
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_ExVccCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PVD_REG_WRITE();
+
+ M4_SYSREG->PWR_PVDCR0_f.EXVCCINEN = ((Enable == enNewState) ? 1u : 0u);
+
+ DISABLE_PVD_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get pvd detection status.
+ **
+ ** \param [in] enPvd The unit of pvd detection.
+ ** \arg PvdU1 The unit1 of pvd detection.
+ ** \arg PvdU2 The unit2 of pvd detection.
+ **
+ ** \retval en_flag_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t PWC_GetPvdStatus(en_pwc_pvd_t enPvd)
+{
+ uint8_t u8flag = 0u;
+
+ switch(enPvd)
+ {
+ case PvdU1:
+ u8flag = M4_SYSREG->PWR_PVDDSR_f.PVD1MON;
+ break;
+ case PvdU2:
+ u8flag = M4_SYSREG->PWR_PVDDSR_f.PVD2MON;
+ break;
+ default:
+ break;
+ }
+
+ return ((1u == u8flag) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get pvd detection flag.
+ **
+ ** \param [in] enPvd The unit of pvd detection.
+ ** \arg PvdU1 The unit1 of pvd detection.
+ ** \arg PvdU2 The unit2 of pvd detection.
+ **
+ ** \retval en_flag_status_t
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+en_flag_status_t PWC_GetPvdFlag(en_pwc_pvd_t enPvd)
+{
+ uint8_t u8flag = 0u;
+
+ switch(enPvd)
+ {
+ case PvdU1:
+ u8flag = M4_SYSREG->PWR_PVDDSR_f.PVD1DETFLG;
+ break;
+ case PvdU2:
+ u8flag = M4_SYSREG->PWR_PVDDSR_f.PVD2DETFLG;
+ break;
+ default:
+ break;
+ }
+
+ return ((1u == u8flag) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear pvd detection flag.
+ **
+ ** \param [in] enPvd The unit of pvd detection.
+ ** \arg PvdU1 The unit1 of pvd detection.
+ ** \arg PvdU2 The unit2 of pvd detection.
+ **
+ ** \note None
+ **
+ ******************************************************************************/
+void PWC_ClearPvdFlag(en_pwc_pvd_t enPvd)
+{
+ ENABLE_PVD_REG_WRITE();
+ switch(enPvd)
+ {
+ case PvdU1:
+ M4_SYSREG->PWR_PVDDSR_f.PVD1MON = 0u;
+ break;
+ case PvdU2:
+ M4_SYSREG->PWR_PVDDSR_f.PVD2MON = 0u;
+ break;
+ default:
+ break;
+ }
+ DISABLE_PVD_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable HRC power.
+ **
+ ** \param [in] enNewState The HRC power state.
+ ** \arg Enable Enable HRC power.
+ ** \arg Disable Disable HRC power.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void PWC_HrcPwrCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_PWRC1_f.VHRCSD = ((Enable == enNewState) ? 0u : 1u);
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable PLL power.
+ **
+ ** \param [in] enNewState The PLL power state.
+ ** \arg Enable Enable PLL power.
+ ** \arg Disable Disable PLL power.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void PWC_PllPwrCmd(en_functional_state_t enNewState)
+{
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
+
+ ENABLE_PWR_REG_WRITE();
+
+ M4_SYSREG->PWR_PWRC1_f.VPLLSD = ((Enable == enNewState) ? 0u : 1u);
+
+ DISABLE_PWR_REG_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief NVIC backup and disable before entry from stop mode
+ **
+ ** param None
+ **
+ ** retval None
+ **
+ *****************************************************************************/
+void PWC_enNvicBackup(void)
+{
+ uint8_t u8Cnt;
+ stc_intc_sel_field_t *stcIntSel;
+ uint32_t u32WakeupSrc = INT_MAX;
+
+ /* Backup NVIC set enable register for IRQ0~143*/
+ for (u8Cnt = 0u; u8Cnt < sizeof(NVIC_ISER_BAK)/sizeof(uint32_t); u8Cnt++)
+ {
+ NVIC_ISER_BAK[u8Cnt] = NVIC->ISER[u8Cnt];
+ }
+
+ /* Disable share vector */
+ for (u8Cnt = 128u; u8Cnt < 144u; u8Cnt++)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+
+ for (u8Cnt = 0u; u8Cnt < 128u; u8Cnt++)
+ {
+ stcIntSel = (stc_intc_sel_field_t *)((uint32_t)(&M4_INTC->SEL0) + (4ul * u8Cnt));
+ /* Disable NVIC if it is the wakeup-able source from stop mode */
+ u32WakeupSrc = stcIntSel->INTSEL;
+ if (IS_VALID_WKUP_SRC(u32WakeupSrc))
+ {
+ switch (stcIntSel->INTSEL)
+ {
+ case INT_USART1_WUPI:
+ if (Reset == bM4_INTC_WUPEN_RXWUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_TMR01_GCMA:
+ if (Reset == bM4_INTC_WUPEN_TMR0WUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_RTC_ALM:
+ if (Reset == bM4_INTC_WUPEN_RTCALMWUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_RTC_PRD:
+ if (Reset == bM4_INTC_WUPEN_RTCPRDWUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_WKTM_PRD:
+ if (Reset == bM4_INTC_WUPEN_WKTMWUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_ACMP1:
+ if (Reset == bM4_INTC_WUPEN_CMPI0WUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PVD_PVD1:
+ if (Reset == bM4_INTC_WUPEN_PVD1WUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PVD_PVD2:
+ if (Reset == bM4_INTC_WUPEN_PVD2WUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_SWDT_REFUDF:
+ if (Reset == bM4_INTC_WUPEN_SWDTWUEN)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ0:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN0)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ1:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN1)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ2:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN2)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ3:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN3)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ4:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN4)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ5:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN5)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ6:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN6)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ7:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN7)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ8:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN8)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ9:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN9)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ10:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN10)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ11:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN11)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ12:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN12)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ13:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN13)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ14:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN14)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ case INT_PORT_EIRQ15:
+ if (Reset == bM4_INTC_WUPEN_EIRQWUEN15)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ /* Disable NVIC for all none-wakeup source */
+ else if (INT_MAX != stcIntSel->INTSEL)
+ {
+ NVIC_DisableIRQ((IRQn_Type)u8Cnt);
+ }
+ else
+ {
+ ;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief NVIC recover after wakeup from stop mode
+ **
+ ** param None
+ **
+ ** retval None
+ **
+ *****************************************************************************/
+void PWC_enNvicRecover(void)
+{
+ uint8_t u8Cnt;
+
+ for (u8Cnt = 0u; u8Cnt < sizeof(NVIC_ISER_BAK)/sizeof(uint32_t); u8Cnt++)
+ {
+ NVIC->ISER[u8Cnt] = NVIC_ISER_BAK[u8Cnt];
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Select system clock source.
+ **
+ ** \param [in] u8SysSrc The system clock source.
+ **
+ ** \retval None
+ **
+ ** \note Must close all of the fcg register before switch system clock source.
+ ** This function only be called in func. PWC_enClockBackup and
+ ** PWC_enClockRecover.
+ ** If need to switch system clock please call CLK_SetSysClkSource.
+ **
+ ******************************************************************************/
+static void PWC_SetSysClk(uint8_t u8SysSrc)
+{
+ __IO uint32_t fcg0 = M4_MSTP->FCG0;
+ __IO uint32_t fcg1 = M4_MSTP->FCG1;
+ __IO uint32_t fcg2 = M4_MSTP->FCG2;
+ __IO uint32_t fcg3 = M4_MSTP->FCG3;
+
+ /* Only current system clock source or target system clock source is MPLL
+ need to close fcg0~fcg3 and open fcg0~fcg3 during switch system clock source.
+ We need to backup fcg0~fcg3 before close them. */
+ if((5u == M4_SYSREG->CMU_CKSWR_f.CKSW) || (5u == u8SysSrc))
+ {
+ /* Close fcg0~fcg3. */
+ M4_MSTP->FCG0 = 0xFFFFFAEEul;
+ M4_MSTP->FCG1 = 0xFFFFFFFFul;
+ M4_MSTP->FCG2 = 0xFFFFFFFFul;
+ M4_MSTP->FCG3 = 0xFFFFFFFFul;
+
+ Ddl_Delay1us(1ul);
+ }
+
+ /* Switch to target system clock source. */
+ ENABLE_PWR_REG0_WRITE();
+
+ M4_SYSREG->CMU_CKSWR_f.CKSW = u8SysSrc;
+
+ DISABLE_PWR_REG0_WRITE();
+
+ /* update system clock frequency. */
+ SystemCoreClockUpdate();
+
+ Ddl_Delay1us(1ul);
+
+ /* Open fcg0~fcg3. */
+ M4_MSTP->FCG0 = fcg0;
+ M4_MSTP->FCG1 = fcg1;
+ M4_MSTP->FCG2 = fcg2;
+ M4_MSTP->FCG3 = fcg3;
+
+ Ddl_Delay1us(1ul);
+}
+/**
+ *******************************************************************************
+ ** \brief Backup HRC/MRC state and system clock , enable HRC/MRC ,set MRC as
+ ** system clock before enter stop mode.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+static void PWC_enClockBackup(void)
+{
+ __IO uint32_t timeout = 0ul;
+ en_flag_status_t status = Reset;
+
+ /* HRC state backup. */
+ u8HrcState = (uint8_t)bM4_SYSREG_CMU_HRCCR_HRCSTP;
+ /* System clock backup*/
+ u8SysClkSrc = M4_SYSREG->CMU_CKSWR_f.CKSW;
+
+ ENABLE_PWR_REG0_WRITE();
+
+ /* Enable HRC before enter stop mode. */
+ if(0u != u8HrcState)
+ {
+ bM4_SYSREG_CMU_HRCCR_HRCSTP = 0u;
+ do
+ {
+ status = (en_flag_status_t)M4_SYSREG->CMU_OSCSTBSR_f.HRCSTBF;
+ timeout++;
+ }while((timeout < 0x1000ul) && (status != Set));
+ }
+ else
+ {
+ /* code */
+ }
+ /* When system clock source is HRC and MPLL, set MRC as system clock. . */
+ if((0u == u8SysClkSrc) || (5u == u8SysClkSrc))
+ {
+ /* MRC state backup. */
+ u8MrcState = (uint8_t)bM4_SYSREG_CMU_MRCCR_MRCSTP;
+ if(0u != u8MrcState)
+ {
+ bM4_SYSREG_CMU_MRCCR_MRCSTP = 0u;
+ __NOP();
+ __NOP();
+ __NOP();
+ __NOP();
+ __NOP();
+ }
+ PWC_SetSysClk(1u);
+ }
+ else
+ {
+ /* code */
+ }
+
+ DISABLE_PWR_REG0_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Recover HRC/MRC state and system clock after wakeup stop mode.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+static void PWC_enClockRecover(void)
+{
+ ENABLE_PWR_REG0_WRITE();
+
+ if((0u == u8SysClkSrc) || (5u == u8SysClkSrc))
+ {
+ /* Recover MRC state & system clock source. */
+ M4_SYSREG->CMU_MRCCR_f.MRCSTP = u8MrcState;
+ PWC_SetSysClk(u8SysClkSrc);
+ }
+ /* Recover HRC state after wakeup stop mode. */
+ M4_SYSREG->CMU_HRCCR_f.HRCSTP = u8HrcState;
+
+ DISABLE_PWR_REG0_WRITE();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clock backup before enter stop mode and mark it.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note This function should be called before func. PWC_EnterStopMd.
+ ******************************************************************************/
+void PWC_ClkBackup(void)
+{
+ /* Disable all interrupt to ensure the following operation continued. */
+ __disable_irq();
+
+ /* HRC/MRC backup and switch system clock as MRC before entry from stop mode. */
+ PWC_enClockBackup();
+
+ /* Mark the system clock has been switch as MRC, and will enter the stop mode. */
+ u8StopFlag = 1u;
+
+ /* Enable all interrupt. */
+ __enable_irq();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clock recover after wakeup stop mode.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note This function should be called after func. PWC_EnterStopMd.
+ ******************************************************************************/
+void PWC_ClkRecover(void)
+{
+ /* Disable all interrupt to ensure the following operation continued. */
+ __disable_irq();
+
+ /* Mark the system clock will be switch as MRC, and has waked_up from stop mode. */
+ u8StopFlag = 0u;
+
+ /* Recover HRC/MRC state and system clock after wakeup stop mode. */
+ PWC_enClockRecover();
+
+ /* Enable all interrupt. */
+ __enable_irq();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clock backup before exit wakup interrupt.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ** \note This function should be called before exit wakup interrput.
+ ******************************************************************************/
+void PWC_IrqClkBackup(void)
+{
+ if((1ul == u8StopFlag) && (1ul == u8WkupIntCnt))
+ {
+ /* HRC/MRC backup and switch system clock as MRC. */
+ PWC_enClockBackup();
+ }
+ u8WkupIntCnt--;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clock recover after enter wakeup interrupt.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+** \note This function should be called after enter wakup interrput.
+ ******************************************************************************/
+void PWC_IrqClkRecover(void)
+{
+ /* The varibale to display how many waked_up interrupt has been occured
+ simultaneously and to decided whether backup clock before exit wake_up
+ interrupt. */
+ u8WkupIntCnt++;
+
+ if(1ul == u8StopFlag)
+ {
+ /* Recover HRC/MRC state and system clock. */
+ PWC_enClockRecover();
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enter stop mode.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void PWC_EnterStopMd(void)
+{
+ /* NVIC backup and disable before entry from stop mode.*/
+ PWC_enNvicBackup();
+ /* Clock backup and switch system clock as MRC before entry from stop mode. */
+ PWC_ClkBackup();
+
+ ENABLE_PWR_REG0_WRITE();
+
+ M4_SYSREG->PWR_STPMCR_f.STOP = 1u;
+ M4_SYSREG->PWR_PWRC0_f.PWDN = 0u;
+
+ DISABLE_PWR_REG0_WRITE();
+
+ __WFI();
+
+ /* Recover HRC/MRC state and system clock after wakeup from stop mode. */
+ PWC_ClkRecover();
+ /* NVIC recover after wakeup from stop mode. */
+ PWC_enNvicRecover();
+}
+
+/**
+ *******************************************************************************
+ ** \brief Switch MCU from low_speed (HCLK < 8MHz) to high-speed (HCLK > 8MHz) mode.
+ **
+ ** \param None
+ **
+ ** \retval Ok: Mode switch sucessfully.
+ **
+ ** \note Called after clock is ready.
+ ******************************************************************************/
+en_result_t PWC_HS2LS(void)
+{
+ uint32_t u32To = 10000ul;
+
+ if(0ul == M4_EFM->FAPRT)
+ {
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x3210ul;
+ M4_EFM->FRMC_f.LVM = 1u;
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x0123ul;
+ }
+ else
+ {
+ M4_EFM->FRMC_f.LVM = 1u;
+ }
+
+ ENABLE_PWR_REG_WRITE();
+ M4_SYSREG->PWR_RAMOPM = 0x9062u;
+ while((0x9062 != M4_SYSREG->PWR_RAMOPM) || (1u != M4_EFM->FRMC_f.LVM))
+ {
+ if (0ul == u32To--)
+ {
+ return Error;
+ }
+ }
+ M4_SYSREG->PWR_PWRC2 = 0xE1U;
+ M4_SYSREG->PWR_MDSWCR = 0x10U;
+ DISABLE_PWR_REG_WRITE();
+
+ Ddl_Delay1ms(1ul);
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Switch MCU from high-speed (HCLK > 8MHz) to low_speed (HCLK < 8MHz) mode.
+ **
+ ** \param None
+ **
+ ** \retval Ok: Mode switch sucessfully.
+ ** Error: Mode switch failure.
+ **
+ ** \note Called before clock is ready.
+ ******************************************************************************/
+en_result_t PWC_LS2HS(void)
+{
+ uint32_t u32To = 10000ul;
+
+ ENABLE_PWR_REG_WRITE();
+ M4_SYSREG->PWR_PWRC2 = 0xFFU;
+ M4_SYSREG->PWR_MDSWCR = 0x10U;
+
+ Ddl_Delay1ms(1ul);
+
+ if(0ul == M4_EFM->FAPRT)
+ {
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x3210ul;
+ M4_EFM->FRMC_f.LVM = 0u;
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x0123ul;
+ }
+ else
+ {
+ M4_EFM->FRMC_f.LVM = 0u;
+ }
+
+ M4_SYSREG->PWR_RAMOPM = 0x8043u;
+ while((0x8043 != M4_SYSREG->PWR_RAMOPM) || (0u != M4_EFM->FRMC_f.LVM))
+ {
+ if (0ul == u32To--)
+ {
+ return Error;
+ }
+ }
+
+ DISABLE_PWR_REG_WRITE();
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Switch MCU from high-speed (HCLK > 8MHz) to high-performance mode.
+ **
+ ** \param None
+ **
+ ** \retval Ok: Mode switch sucessfully.
+ ** Error: Mode switch failure.
+ **
+ ** \note Called before clock is ready.
+ ******************************************************************************/
+en_result_t PWC_HS2HP(void)
+{
+ ENABLE_PWR_REG_WRITE();
+ M4_SYSREG->PWR_PWRC2 = 0xCFU;
+ M4_SYSREG->PWR_MDSWCR = 0x10U;
+ DISABLE_PWR_REG_WRITE();
+ Ddl_Delay1ms(1ul);
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Switch MCU from high-performance to high-speed (HCLK > 8MHz) mode.
+ **
+ ** \param None
+ **
+ ** \retval Ok: Mode switch sucessfully.
+ ** Error: Mode switch failure.
+ **
+ ** \note Called after clock is ready.
+ ******************************************************************************/
+en_result_t PWC_HP2HS(void)
+{
+ ENABLE_PWR_REG_WRITE();
+ M4_SYSREG->PWR_PWRC2 = 0xFFU;
+ M4_SYSREG->PWR_MDSWCR = 0x10U;
+ DISABLE_PWR_REG_WRITE();
+ Ddl_Delay1ms(1ul);
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Switch MCU from low-speed (HCLK <= 8MHz) to high-performance mode.
+ **
+ ** \param None
+ **
+ ** \retval Ok: Mode switch sucessfully.
+ ** Error: Mode switch failure.
+ **
+ ** \note Called before clock is ready.
+ ******************************************************************************/
+en_result_t PWC_LS2HP(void)
+{
+ uint32_t u32To = 10000ul;
+
+ ENABLE_PWR_REG_WRITE();
+ M4_SYSREG->PWR_PWRC2 = 0xCFU;
+ M4_SYSREG->PWR_MDSWCR = 0x10U;
+
+ Ddl_Delay1ms(1);
+
+ if(0ul == M4_EFM->FAPRT)
+ {
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x3210ul;
+ M4_EFM->FRMC_f.LVM = 0u;
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x0123ul;
+ }
+ else
+ {
+ M4_EFM->FRMC_f.LVM = 0u;
+ }
+
+ M4_SYSREG->PWR_RAMOPM = 0x8043u;
+ while((0x8043 != M4_SYSREG->PWR_RAMOPM) || (0u != M4_EFM->FRMC_f.LVM))
+ {
+ if (0ul == u32To--)
+ {
+ return Error;
+ }
+ }
+
+ DISABLE_PWR_REG_WRITE();
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Switch MCU from high-performance to low-speed (HCLK <= 8MHz) mode.
+ **
+ ** \param None
+ **
+ ** \retval Ok: Mode switch sucessfully.
+ ** Error: Mode switch failure.
+ **
+ ** \note Called after clock is ready.
+ ******************************************************************************/
+en_result_t PWC_HP2LS(void)
+{
+ uint32_t u32To = 10000ul;
+
+ if(0ul == M4_EFM->FAPRT)
+ {
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x3210ul;
+ M4_EFM->FRMC_f.LVM = 1u;
+ M4_EFM->FAPRT = 0x0123ul;
+ M4_EFM->FAPRT = 0x0123ul;
+ }
+ else
+ {
+ M4_EFM->FRMC_f.LVM = 1u;
+ }
+
+ ENABLE_PWR_REG_WRITE();
+ M4_SYSREG->PWR_RAMOPM = 0x9062u;
+ u32To = 10000ul;
+ while((0x9062 != M4_SYSREG->PWR_RAMOPM) || (1u != M4_EFM->FRMC_f.LVM))
+ {
+ if (0ul == u32To--)
+ {
+ return Error;
+ }
+ }
+
+ M4_SYSREG->PWR_PWRC2 = 0xD1U;
+ M4_SYSREG->PWR_MDSWCR = 0x10U;
+
+ DISABLE_PWR_REG_WRITE();
+
+ Ddl_Delay1ms(1);
+
+ return Ok;
+}
+
+//@} // PwcGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_qspi.c b/lib/hc32f460/driver/src/hc32f460_qspi.c new file mode 100644 index 00000000..5edd4e94 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_qspi.c @@ -0,0 +1,752 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_qspi.c
+ **
+ ** A detailed description is available at
+ ** @link QspiGroup Queued SPI description @endlink
+ **
+ ** - 2018-11-20 CDT First version for Device Driver Library of Qspi.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_qspi.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup QspiGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for clock division */
+#define IS_VALID_CLK_DIV(x) \
+( ((x) == QspiHclkDiv2) || \
+ (((x) >= QspiHclkDiv3) && ((x) <= QspiHclkDiv64)))
+
+/*!< Parameter valid check for spi mode */
+#define IS_VALID_SPI_MODE(x) \
+( (QspiSpiMode0 == (x)) || \
+ (QspiSpiMode3 == (x)))
+
+/*!< Parameter valid check for bus communication mode */
+#define IS_VALID_BUS_COMM_MODE(x) \
+( (QspiBusModeRomAccess == (x)) || \
+ (QspiBusModeDirectAccess == (x)))
+
+/*!< Parameter valid check for prefetch stop location */
+#define IS_VALID_PREFETCH_STOP_LOCATION(x) \
+( (QspiPrefetchStopComplete == (x)) || \
+ (QspiPrefetchStopImmediately == (x)))
+
+/*!< Parameter valid check for receive data protocol */
+#define IS_VALID_RECE_DATA_PROTOCOL(x) \
+( (QspiProtocolExtendSpi == (x)) || \
+ (QspiProtocolTwoWiresSpi == (x)) || \
+ (QspiProtocolFourWiresSpi == (x)))
+
+/*!< Parameter valid check for transmit address protocol */
+#define IS_VALID_TRANS_ADDR_PROTOCOL(x) \
+( (QspiProtocolExtendSpi == (x)) || \
+ (QspiProtocolTwoWiresSpi == (x)) || \
+ (QspiProtocolFourWiresSpi == (x)))
+
+/*!< Parameter valid check for transmit instruction protocol */
+#define IS_VALID_TRANS_INSTRUCT_PROTOCOL(x) \
+( (QspiProtocolExtendSpi == (x)) || \
+ (QspiProtocolTwoWiresSpi == (x)) || \
+ (QspiProtocolFourWiresSpi == (x)))
+
+/*!< Parameter valid check for serial interface read mode */
+#define IS_VALID_INTERFACE_READ_MODE(x) \
+( (QspiReadModeStandard == (x)) || \
+ (QspiReadModeFast == (x)) || \
+ (QspiReadModeTwoWiresOutput == (x)) || \
+ (QspiReadModeTwoWiresIO == (x)) || \
+ (QspiReadModeFourWiresOutput == (x)) || \
+ (QspiReadModeFourWiresIO == (x)) || \
+ (QspiReadModeCustomStandard == (x)) || \
+ (QspiReadModeCustomFast == (x)))
+
+/*!< Parameter valid check for QSSN valid extend delay time */
+#define IS_VALID_QSSN_VALID_EXTEND_TIME(x) \
+( (QspiQssnValidExtendNot == (x)) || \
+ (QspiQssnValidExtendSck32 == (x)) || \
+ (QspiQssnValidExtendSck128 == (x)) || \
+ (QspiQssnValidExtendSckEver == (x)))
+
+/*!< Parameter valid check for QSSN minimum interval time */
+#define IS_VALID_QSSN_INTERVAL_TIME(x) \
+( (QspiQssnIntervalQsck1 == (x)) || \
+ (QspiQssnIntervalQsck2 == (x)) || \
+ (QspiQssnIntervalQsck3 == (x)) || \
+ (QspiQssnIntervalQsck4 == (x)) || \
+ (QspiQssnIntervalQsck5 == (x)) || \
+ (QspiQssnIntervalQsck6 == (x)) || \
+ (QspiQssnIntervalQsck7 == (x)) || \
+ (QspiQssnIntervalQsck8 == (x)) || \
+ (QspiQssnIntervalQsck9 == (x)) || \
+ (QspiQssnIntervalQsck10 == (x)) || \
+ (QspiQssnIntervalQsck11 == (x)) || \
+ (QspiQssnIntervalQsck12 == (x)) || \
+ (QspiQssnIntervalQsck13 == (x)) || \
+ (QspiQssnIntervalQsck14 == (x)) || \
+ (QspiQssnIntervalQsck15 == (x)) || \
+ (QspiQssnIntervalQsck16 <= (x)))
+
+/*!< Parameter valid check for QSCK duty correction */
+#define IS_VALID_QSCK_DUTY_CORR(x) \
+( (QspiQsckDutyCorrNot == (x)) || \
+ (QspiQsckDutyCorrHalfHclk == (x)))
+
+/*!< Parameter valid check for virtual cycles */
+#define IS_VALID_VIRTUAL_CYCLES(x) \
+( (QspiVirtualPeriodQsck3 == (x)) || \
+ (QspiVirtualPeriodQsck4 == (x)) || \
+ (QspiVirtualPeriodQsck5 == (x)) || \
+ (QspiVirtualPeriodQsck6 == (x)) || \
+ (QspiVirtualPeriodQsck7 == (x)) || \
+ (QspiVirtualPeriodQsck8 == (x)) || \
+ (QspiVirtualPeriodQsck9 == (x)) || \
+ (QspiVirtualPeriodQsck10 == (x)) || \
+ (QspiVirtualPeriodQsck11 == (x)) || \
+ (QspiVirtualPeriodQsck12 == (x)) || \
+ (QspiVirtualPeriodQsck13 == (x)) || \
+ (QspiVirtualPeriodQsck14 == (x)) || \
+ (QspiVirtualPeriodQsck15 == (x)) || \
+ (QspiVirtualPeriodQsck16 == (x)) || \
+ (QspiVirtualPeriodQsck17 == (x)) || \
+ (QspiVirtualPeriodQsck18 == (x)))
+
+/*!< Parameter valid check for WP pin output level */
+#define IS_VALID_WP_OUTPUT_LEVEL(x) \
+( (QspiWpPinOutputLow == (x)) || \
+ (QspiWpPinOutputHigh == (x)))
+
+/*!< Parameter valid check for QSSN setup delay time */
+#define IS_VALID_QSSN_SETUP_DELAY(x) \
+( (QspiQssnSetupDelayHalfQsck == (x)) || \
+ (QspiQssnSetupDelay1Dot5Qsck == (x)))
+
+/*!< Parameter valid check for QSSN hold delay time */
+#define IS_VALID_QSSN_HOLD_TIME(x) \
+( (QspiQssnHoldDelayHalfQsck == (x)) || \
+ (QspiQssnHoldDelay1Dot5Qsck == (x)))
+
+/*!< Parameter valid check for interface address width */
+#define IS_VALID_INTERFACE_ADDR_WIDTH(x) \
+( (QspiAddressByteOne == (x)) || \
+ (QspiAddressByteTwo == (x)) || \
+ (QspiAddressByteThree == (x)) || \
+ (QspiAddressByteFour == (x)))
+
+/*!< Parameter valid check for extend address */
+#define IS_VALID_SET_EXTEND_ADDR(x) ((x) <= 0x3Fu)
+
+/*!< Parameter valid check for get flag type */
+#define IS_VALID_GET_FLAG_TYPE(x) \
+( (QspiFlagBusBusy == (x)) || \
+ (QspiFlagXipMode == (x)) || \
+ (QspiFlagRomAccessError == (x)) || \
+ (QspiFlagPrefetchBufferFull == (x)) || \
+ (QspiFlagPrefetchStop == (x)))
+
+/*!< Parameter valid check for clear flag type */
+#define IS_VALID_CLEAR_FLAG_TYPE(x) (QspiFlagRomAccessError == (x))
+
+/*!< QSPI registers reset value */
+#define QSPI_REG_CR_RESET_VALUE (0x003F0000ul)
+#define QSPI_REG_CSCR_RESET_VALUE (0x0000000Ful)
+#define QSPI_REG_FCR_RESET_VALUE (0x000080B3ul)
+#define QSPI_REG_SR_RESET_VALUE (0x00008000ul)
+#define QSPI_REG_CCMD_RESET_VALUE (0x00000000ul)
+#define QSPI_REG_XCMD_RESET_VALUE (0x000000FFul)
+#define QSPI_REG_EXAR_RESET_VALUE (0x00000000ul)
+#define QSPI_REG_SR2_RESET_VALUE (0x00000000ul)
+#define QSPI_REG_DCOM_RESET_VALUE (0x00000000ul)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief De-Initialize QSPI unit
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_DeInit(void)
+{
+ en_result_t enRet = Ok;
+
+ M4_QSPI->CR = QSPI_REG_CR_RESET_VALUE;
+ if (1u == M4_QSPI->SR_f.RAER)
+ {
+ M4_QSPI->SR2_f.RAERCLR = 1u;
+ }
+ M4_QSPI->CSCR = QSPI_REG_CSCR_RESET_VALUE;
+ M4_QSPI->FCR = QSPI_REG_FCR_RESET_VALUE;
+ M4_QSPI->EXAR = QSPI_REG_EXAR_RESET_VALUE;
+ M4_QSPI->SR = QSPI_REG_SR_RESET_VALUE;
+ M4_QSPI->CCMD = QSPI_REG_CCMD_RESET_VALUE;
+ M4_QSPI->XCMD = QSPI_REG_XCMD_RESET_VALUE;
+ M4_QSPI->DCOM = QSPI_REG_DCOM_RESET_VALUE;
+ M4_QSPI->SR2 = QSPI_REG_SR2_RESET_VALUE;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize QSPI unit
+ **
+ ** \param [in] pstcQspiInitCfg Pointer to qspi configuration
+ ** \arg See the struct #stc_qspi_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t QSPI_Init(const stc_qspi_init_t *pstcQspiInitCfg)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcQspiInitCfg)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CLK_DIV(pstcQspiInitCfg->enClkDiv));
+ DDL_ASSERT(IS_VALID_SPI_MODE(pstcQspiInitCfg->enSpiMode));
+ DDL_ASSERT(IS_VALID_BUS_COMM_MODE(pstcQspiInitCfg->enBusCommMode));
+ DDL_ASSERT(IS_VALID_PREFETCH_STOP_LOCATION(pstcQspiInitCfg->enPrefetchMode));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcQspiInitCfg->enPrefetchFuncEn));
+ DDL_ASSERT(IS_VALID_RECE_DATA_PROTOCOL(pstcQspiInitCfg->stcCommProtocol.enReceProtocol));
+ DDL_ASSERT(IS_VALID_TRANS_ADDR_PROTOCOL(pstcQspiInitCfg->stcCommProtocol.enTransAddrProtocol));
+ DDL_ASSERT(IS_VALID_TRANS_INSTRUCT_PROTOCOL(pstcQspiInitCfg->stcCommProtocol.enTransInstrProtocol));
+ DDL_ASSERT(IS_VALID_INTERFACE_READ_MODE(pstcQspiInitCfg->stcCommProtocol.enReadMode));
+ DDL_ASSERT(IS_VALID_QSSN_VALID_EXTEND_TIME(pstcQspiInitCfg->enQssnValidExtendTime));
+ DDL_ASSERT(IS_VALID_QSSN_INTERVAL_TIME(pstcQspiInitCfg->enQssnIntervalTime));
+ DDL_ASSERT(IS_VALID_QSCK_DUTY_CORR(pstcQspiInitCfg->enQsckDutyCorr));
+ DDL_ASSERT(IS_VALID_VIRTUAL_CYCLES(pstcQspiInitCfg->enVirtualPeriod));
+ DDL_ASSERT(IS_VALID_WP_OUTPUT_LEVEL(pstcQspiInitCfg->enWpPinLevel));
+ DDL_ASSERT(IS_VALID_QSSN_SETUP_DELAY(pstcQspiInitCfg->enQssnSetupDelayTime));
+ DDL_ASSERT(IS_VALID_QSSN_HOLD_TIME(pstcQspiInitCfg->enQssnHoldDelayTime));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcQspiInitCfg->enFourByteAddrReadEn));
+ DDL_ASSERT(IS_VALID_INTERFACE_ADDR_WIDTH(pstcQspiInitCfg->enAddrWidth));
+
+ /* Configure control register */
+ M4_QSPI->CR_f.DIV = pstcQspiInitCfg->enClkDiv;
+ M4_QSPI->CR_f.SPIMD3 = pstcQspiInitCfg->enSpiMode;
+ M4_QSPI->CR_f.PFE = pstcQspiInitCfg->enPrefetchFuncEn;
+ M4_QSPI->CR_f.PFSAE = pstcQspiInitCfg->enPrefetchMode;
+ M4_QSPI->CR_f.MDSEL = pstcQspiInitCfg->stcCommProtocol.enReadMode;
+
+ /* Custom read mode */
+ if ((QspiReadModeCustomFast == pstcQspiInitCfg->stcCommProtocol.enReadMode) ||
+ (QspiReadModeCustomStandard == pstcQspiInitCfg->stcCommProtocol.enReadMode))
+ {
+ M4_QSPI->CR_f.IPRSL = pstcQspiInitCfg->stcCommProtocol.enTransInstrProtocol;
+ M4_QSPI->CR_f.APRSL = pstcQspiInitCfg->stcCommProtocol.enTransAddrProtocol;
+ M4_QSPI->CR_f.DPRSL = pstcQspiInitCfg->stcCommProtocol.enReceProtocol;
+ }
+ else
+ {
+ M4_QSPI->CR_f.IPRSL = QspiProtocolExtendSpi;
+ M4_QSPI->CR_f.APRSL = QspiProtocolExtendSpi;
+ M4_QSPI->CR_f.DPRSL = QspiProtocolExtendSpi;
+ }
+
+ /* Configure chip select control register */
+ M4_QSPI->CSCR_f.SSNW = pstcQspiInitCfg->enQssnValidExtendTime;
+ M4_QSPI->CSCR_f.SSHW = pstcQspiInitCfg->enQssnIntervalTime;
+
+ /* Configure format control register */
+ if (((pstcQspiInitCfg->enClkDiv % 2) != 0) &&
+ (pstcQspiInitCfg->enQsckDutyCorr != QspiQsckDutyCorrNot))
+ {
+ M4_QSPI->FCR_f.DUTY = QspiQsckDutyCorrNot;
+ }
+ else
+ {
+ M4_QSPI->FCR_f.DUTY = pstcQspiInitCfg->enQsckDutyCorr;
+ }
+ M4_QSPI->FCR_f.DMCYCN = pstcQspiInitCfg->enVirtualPeriod;
+ M4_QSPI->FCR_f.WPOL = pstcQspiInitCfg->enWpPinLevel;
+ M4_QSPI->FCR_f.SSNLD = pstcQspiInitCfg->enQssnSetupDelayTime;
+ M4_QSPI->FCR_f.SSNHD = pstcQspiInitCfg->enQssnHoldDelayTime;
+ M4_QSPI->FCR_f.FOUR_BIC = pstcQspiInitCfg->enFourByteAddrReadEn;
+ M4_QSPI->FCR_f.AWSL = pstcQspiInitCfg->enAddrWidth;
+ M4_QSPI->CR_f.DCOME = pstcQspiInitCfg->enBusCommMode;
+
+ /* Configure ROM access instruction */
+ M4_QSPI->CCMD = pstcQspiInitCfg->u8RomAccessInstr;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Config communication protocol structure
+ **
+ ** \param [in] pstcCommProtocol Pointer to qspi communication protocol configuration
+ ** \arg See the struct #stc_qspi_comm_protocol_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t QSPI_CommProtocolConfig(const stc_qspi_comm_protocol_t *pstcCommProtocol)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcCommProtocol)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_RECE_DATA_PROTOCOL(pstcCommProtocol->enReceProtocol));
+ DDL_ASSERT(IS_VALID_TRANS_ADDR_PROTOCOL(pstcCommProtocol->enTransAddrProtocol));
+ DDL_ASSERT(IS_VALID_TRANS_INSTRUCT_PROTOCOL(pstcCommProtocol->enTransInstrProtocol));
+ DDL_ASSERT(IS_VALID_INTERFACE_READ_MODE(pstcCommProtocol->enReadMode));
+
+ M4_QSPI->CR_f.MDSEL = pstcCommProtocol->enReadMode;
+ /* Custom read mode */
+ if ((QspiReadModeCustomFast == pstcCommProtocol->enReadMode) ||
+ (QspiReadModeCustomStandard == pstcCommProtocol->enReadMode))
+ {
+ M4_QSPI->CR_f.IPRSL = pstcCommProtocol->enTransInstrProtocol;
+ M4_QSPI->CR_f.APRSL = pstcCommProtocol->enTransAddrProtocol;
+ M4_QSPI->CR_f.DPRSL = pstcCommProtocol->enReceProtocol;
+ }
+ else
+ {
+ M4_QSPI->CR_f.IPRSL = QspiProtocolExtendSpi;
+ M4_QSPI->CR_f.APRSL = QspiProtocolExtendSpi;
+ M4_QSPI->CR_f.DPRSL = QspiProtocolExtendSpi;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable prefetch function
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable prefetch function
+ ** \arg Enable Enable prefetch function
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_PrefetchCmd(en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_QSPI->CR_f.PFE = enNewSta;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set clock division
+ **
+ ** \param [in] enClkDiv Clock division
+ ** \arg QspiHclkDiv2 Clock source: HCLK/2
+ ** \arg QspiHclkDiv3 Clock source: HCLK/3
+ ** \arg QspiHclkDiv4 Clock source: HCLK/4
+ ** \arg QspiHclkDiv5 Clock source: HCLK/5
+ ** \arg QspiHclkDiv6 Clock source: HCLK/6
+ ** \arg QspiHclkDiv7 Clock source: HCLK/7
+ ** \arg QspiHclkDiv8 Clock source: HCLK/8
+ ** \arg QspiHclkDiv9 Clock source: HCLK/9
+ ** \arg QspiHclkDiv10 Clock source: HCLK/10
+ ** \arg QspiHclkDiv11 Clock source: HCLK/11
+ ** \arg QspiHclkDiv12 Clock source: HCLK/12
+ ** \arg QspiHclkDiv13 Clock source: HCLK/13
+ ** \arg QspiHclkDiv14 Clock source: HCLK/14
+ ** \arg QspiHclkDiv15 Clock source: HCLK/15
+ ** \arg QspiHclkDiv16 Clock source: HCLK/16
+ ** \arg QspiHclkDiv17 Clock source: HCLK/17
+ ** \arg QspiHclkDiv18 Clock source: HCLK/18
+ ** \arg QspiHclkDiv19 Clock source: HCLK/19
+ ** \arg QspiHclkDiv20 Clock source: HCLK/20
+ ** \arg QspiHclkDiv21 Clock source: HCLK/21
+ ** \arg QspiHclkDiv22 Clock source: HCLK/22
+ ** \arg QspiHclkDiv23 Clock source: HCLK/23
+ ** \arg QspiHclkDiv24 Clock source: HCLK/24
+ ** \arg QspiHclkDiv25 Clock source: HCLK/25
+ ** \arg QspiHclkDiv26 Clock source: HCLK/26
+ ** \arg QspiHclkDiv27 Clock source: HCLK/27
+ ** \arg QspiHclkDiv28 Clock source: HCLK/28
+ ** \arg QspiHclkDiv29 Clock source: HCLK/29
+ ** \arg QspiHclkDiv30 Clock source: HCLK/30
+ ** \arg QspiHclkDiv31 Clock source: HCLK/31
+ ** \arg QspiHclkDiv32 Clock source: HCLK/32
+ ** \arg QspiHclkDiv33 Clock source: HCLK/33
+ ** \arg QspiHclkDiv34 Clock source: HCLK/34
+ ** \arg QspiHclkDiv35 Clock source: HCLK/35
+ ** \arg QspiHclkDiv36 Clock source: HCLK/36
+ ** \arg QspiHclkDiv37 Clock source: HCLK/37
+ ** \arg QspiHclkDiv38 Clock source: HCLK/38
+ ** \arg QspiHclkDiv39 Clock source: HCLK/39
+ ** \arg QspiHclkDiv40 Clock source: HCLK/40
+ ** \arg QspiHclkDiv41 Clock source: HCLK/41
+ ** \arg QspiHclkDiv42 Clock source: HCLK/42
+ ** \arg QspiHclkDiv43 Clock source: HCLK/43
+ ** \arg QspiHclkDiv44 Clock source: HCLK/44
+ ** \arg QspiHclkDiv45 Clock source: HCLK/45
+ ** \arg QspiHclkDiv46 Clock source: HCLK/46
+ ** \arg QspiHclkDiv47 Clock source: HCLK/47
+ ** \arg QspiHclkDiv48 Clock source: HCLK/48
+ ** \arg QspiHclkDiv49 Clock source: HCLK/49
+ ** \arg QspiHclkDiv50 Clock source: HCLK/50
+ ** \arg QspiHclkDiv51 Clock source: HCLK/51
+ ** \arg QspiHclkDiv52 Clock source: HCLK/52
+ ** \arg QspiHclkDiv53 Clock source: HCLK/53
+ ** \arg QspiHclkDiv54 Clock source: HCLK/54
+ ** \arg QspiHclkDiv55 Clock source: HCLK/55
+ ** \arg QspiHclkDiv56 Clock source: HCLK/56
+ ** \arg QspiHclkDiv57 Clock source: HCLK/57
+ ** \arg QspiHclkDiv58 Clock source: HCLK/58
+ ** \arg QspiHclkDiv59 Clock source: HCLK/59
+ ** \arg QspiHclkDiv60 Clock source: HCLK/60
+ ** \arg QspiHclkDiv61 Clock source: HCLK/61
+ ** \arg QspiHclkDiv62 Clock source: HCLK/62
+ ** \arg QspiHclkDiv63 Clock source: HCLK/63
+ ** \arg QspiHclkDiv64 Clock source: HCLK/64
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_SetClockDiv(en_qspi_clk_div_t enClkDiv)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_CLK_DIV(enClkDiv));
+
+ M4_QSPI->CR_f.DIV = enClkDiv;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set WP Pin level
+ **
+ ** \param [in] enWpLevel WP pin level
+ ** \arg QspiWpPinOutputLow WP pin(QIO2) output low level
+ ** \arg QspiWpPinOutputHigh WP pin(QIO2) output high level
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_SetWPPinLevel(en_qspi_wp_pin_level_t enWpLevel)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_WP_OUTPUT_LEVEL(enWpLevel));
+
+ M4_QSPI->FCR_f.WPOL = enWpLevel;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set communication address width
+ **
+ ** \param [in] enAddrWidth Communication address width
+ ** \arg QspiAddressByteOne One byte address
+ ** \arg QspiAddressByteTwo Two byte address
+ ** \arg QspiAddressByteThree Three byte address
+ ** \arg QspiAddressByteFour Four byte address
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_SetAddrWidth(en_qspi_addr_width_t enAddrWidth)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_INTERFACE_ADDR_WIDTH(enAddrWidth));
+
+ M4_QSPI->FCR_f.AWSL = enAddrWidth;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set extend address value
+ **
+ ** \param [in] u8Addr Extend address value
+ ** \arg 0~0x3F
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_SetExtendAddress(uint8_t u8Addr)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_SET_EXTEND_ADDR(u8Addr));
+
+ M4_QSPI->EXAR_f.EXADR = u8Addr;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set rom access instruction
+ **
+ ** \param [in] u8Instr Rom access instruction
+ ** \arg 0~0xFF
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_SetRomAccessInstruct(uint8_t u8Instr)
+{
+ en_result_t enRet = Ok;
+
+ M4_QSPI->CCMD = u8Instr;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write direct communication value
+ **
+ ** \param [in] u8Val Direct communication value
+ ** \arg 0~0xFF
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_WriteDirectCommValue(uint8_t u8Val)
+{
+ en_result_t enRet = Ok;
+
+ M4_QSPI->DCOM = u8Val;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read direct communication value
+ **
+ ** \param [in] None
+ **
+ ** \retval uint8_t Direct communication read value
+ **
+ ******************************************************************************/
+uint8_t QSPI_ReadDirectCommValue(void)
+{
+ return ((uint8_t)M4_QSPI->DCOM);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable xip mode
+ **
+ ** \param [in] u8Instr Enable or disable xip mode instruction
+ ** \arg 0~0xFF
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable xip mode
+ ** \arg Enable Enable xip mode
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_XipModeCmd(uint8_t u8Instr, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_QSPI->XCMD = u8Instr;
+ if (Enable == enNewSta)
+ {
+ M4_QSPI->CR_f.XIPE = 1u;
+ }
+ else
+ {
+ M4_QSPI->CR_f.XIPE = 0u;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enter direct communication mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ **
+ ** \note If you are in XIP mode, you need to exit XIP mode and then start direct communication mode.
+ **
+ ******************************************************************************/
+en_result_t QSPI_EnterDirectCommMode(void)
+{
+ en_result_t enRet = Ok;
+
+ M4_QSPI->CR_f.DCOME = 1u;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Exit direct communication mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t QSPI_ExitDirectCommMode(void)
+{
+ en_result_t enRet = Ok;
+
+ M4_QSPI->CR_f.DCOME = 0u;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get prefetch buffer current byte number
+ **
+ ** \param [in] None
+ **
+ ** \retval uint8_t Current buffer byte number
+ **
+ ******************************************************************************/
+uint8_t QSPI_GetPrefetchBufferNum(void)
+{
+ return ((uint8_t)M4_QSPI->SR_f.PFNUM);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get flag status
+ **
+ ** \param [in] enFlag Choose need get status's flag
+ ** \arg QspiFlagBusBusy QSPI bus work status flag in direct communication mode
+ ** \arg QspiFlagXipMode XIP mode status signal
+ ** \arg QspiFlagRomAccessError Trigger rom access error flag in direct communication mode
+ ** \arg QspiFlagPrefetchBufferFull Prefetch buffer area status signal
+ ** \arg QspiFlagPrefetchStop Prefetch action status signal
+ **
+ ** \retval Set Flag is set
+ ** \retval Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t QSPI_GetFlag(en_qspi_flag_type_t enFlag)
+{
+ en_flag_status_t enFlagSta = Reset;
+
+ DDL_ASSERT(IS_VALID_GET_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case QspiFlagBusBusy:
+ enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.BUSY;
+ break;
+ case QspiFlagXipMode:
+ enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.XIPF;
+ break;
+ case QspiFlagRomAccessError:
+ enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.RAER;
+ break;
+ case QspiFlagPrefetchBufferFull:
+ enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.PFFUL;
+ break;
+ case QspiFlagPrefetchStop:
+ enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.PFAN;
+ break;
+ default:
+ break;
+ }
+
+ return enFlagSta;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear flag status
+ **
+ ** \param [in] enFlag Choose need get status's flag
+ ** \arg QspiFlagRomAccessError Trigger rom access error flag in direct communication mode
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter Parameter error
+ **
+ ******************************************************************************/
+en_result_t QSPI_ClearFlag(en_qspi_flag_type_t enFlag)
+{
+ en_result_t enRet = Ok;
+
+ if (QspiFlagRomAccessError == enFlag)
+ {
+ M4_QSPI->SR2_f.RAERCLR = 1u;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+//@} // QspiGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_rmu.c b/lib/hc32f460/driver/src/hc32f460_rmu.c new file mode 100644 index 00000000..64a1eaad --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_rmu.c @@ -0,0 +1,139 @@ +/******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_rmu.c
+ **
+ ** A detailed description is available at
+ ** @link RmuGroup RMU description @endlink
+ **
+ ** - 2018-10-28 CDT First version for Device Driver Library of RMU.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_rmu.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup RmuGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#define ENABLE_RMU_REG_WRITE() (M4_SYSREG->PWR_FPRC = 0xa502u)
+#define DISABLE_RMU_REG_WRITE() (M4_SYSREG->PWR_FPRC = 0xa500u)
+
+#define RMU_FLAG_TIM ((uint16_t)0x1000u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Get the chip reset cause.
+ **
+ ** \param [in] pstcData Pointer to return reset cause structure.
+ **
+ ** \retval Ok Get successfully.
+ **
+ ******************************************************************************/
+en_result_t RMU_GetResetCause(stc_rmu_rstcause_t *pstcData)
+{
+ uint16_t u16RstCause = 0u;
+ stc_sysreg_rmu_rstf0_field_t *RMU_RSTF0_f = NULL;
+
+ if(NULL == pstcData)
+ {
+ return ErrorInvalidParameter;
+ }
+
+ u16RstCause = M4_SYSREG->RMU_RSTF0;
+ RMU_RSTF0_f = (stc_sysreg_rmu_rstf0_field_t *)(&u16RstCause);
+
+ pstcData->enMultiRst = (en_flag_status_t)(RMU_RSTF0_f->MULTIRF == 1u);
+ pstcData->enXtalErr = (en_flag_status_t)(RMU_RSTF0_f->XTALERF == 1u);
+ pstcData->enClkFreqErr = (en_flag_status_t)(RMU_RSTF0_f->CKFERF == 1u);
+ pstcData->enRamEcc = (en_flag_status_t)(RMU_RSTF0_f->RAECRF == 1u);
+ pstcData->enRamParityErr = (en_flag_status_t)(RMU_RSTF0_f->RAPERF == 1u);
+ pstcData->enMpuErr = (en_flag_status_t)(RMU_RSTF0_f->MPUERF == 1u);
+ pstcData->enSoftware = (en_flag_status_t)(RMU_RSTF0_f->SWRF == 1u);
+ pstcData->enPowerDown = (en_flag_status_t)(RMU_RSTF0_f->PDRF == 1u);
+ pstcData->enSwdt = (en_flag_status_t)(RMU_RSTF0_f->SWDRF == 1u);
+ pstcData->enWdt = (en_flag_status_t)(RMU_RSTF0_f->WDRF == 1u);
+ pstcData->enPvd2 = (en_flag_status_t)(RMU_RSTF0_f->PVD2RF == 1u);
+ pstcData->enPvd1 = (en_flag_status_t)(RMU_RSTF0_f->PVD2RF == 1u);
+ pstcData->enBrownOut = (en_flag_status_t)(RMU_RSTF0_f->BORF == 1u);
+ pstcData->enRstPin = (en_flag_status_t)(RMU_RSTF0_f->PINRF == 1u);
+ pstcData->enPowerOn = (en_flag_status_t)(RMU_RSTF0_f->PORF == 1u);
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the reset flag.
+ **
+ ** \param None
+ **
+ ** \retval Ok Clear successfully.
+ **
+ ** \note clear reset flag should be done after read RMU_RSTF0 register.
+ ******************************************************************************/
+en_result_t RMU_ClrResetFlag(void)
+{
+ uint16_t u16status = 0u;
+ uint32_t u32timeout = 0u;
+
+ ENABLE_RMU_REG_WRITE();
+
+ do
+ {
+ u32timeout++;
+ M4_SYSREG->RMU_RSTF0_f.CLRF = 1u;
+ u16status = M4_SYSREG->RMU_RSTF0;
+ }while((u32timeout != RMU_FLAG_TIM) && u16status);
+
+ DISABLE_RMU_REG_WRITE();
+
+ if(u32timeout >= RMU_FLAG_TIM)
+ {
+ return ErrorTimeout;
+ }
+
+ return Ok;
+}
+
+
+//@} // RmuGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
+
diff --git a/lib/hc32f460/driver/src/hc32f460_rtc.c b/lib/hc32f460/driver/src/hc32f460_rtc.c new file mode 100644 index 00000000..45695d96 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_rtc.c @@ -0,0 +1,974 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_rtc.c
+ **
+ ** A detailed description is available at
+ ** @link RtcGroup Real-Time Clock description @endlink
+ **
+ ** - 2018-11-22 CDT First version for Device Driver Library of RTC.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_rtc.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup RtcGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for clock source type */
+#define IS_VALID_CLK_SOURCE_TYPE(x) \
+( (RtcClkXtal32 == (x)) || \
+ (RtcClkLrc == (x)))
+
+/*!< Parameter valid check for period interrupt condition */
+#define IS_VALID_PERIOD_INT_CONDITION(x) \
+( (RtcPeriodIntInvalid == (x)) || \
+ (RtcPeriodIntHalfSec == (x)) || \
+ (RtcPeriodIntOneSec == (x)) || \
+ (RtcPeriodIntOneMin == (x)) || \
+ (RtcPeriodIntOneHour == (x)) || \
+ (RtcPeriodIntOneDay == (x)) || \
+ (RtcPeriodIntOneMon == (x)))
+
+/*!< Parameter valid check for time format */
+#define IS_VALID_TIME_FORMAT(x) \
+( (RtcTimeFormat12Hour == (x)) || \
+ (RtcTimeFormat24Hour == (x)))
+
+/*!< Parameter valid check for compensation way */
+#define IS_VALID_COMPEN_WAY(x) \
+( (RtcOutputCompenDistributed == (x)) || \
+ (RtcOutputCompenUniform == (x)))
+
+/*!< Parameter valid check for compensation value range */
+#define IS_VALID_COMPEN_VALUE_RANGE(x) ((x) <= 0x1FFu)
+
+/*!< Parameter valid check for data format */
+#define IS_VALID_DATA_FORMAT(x) \
+( (RtcDataFormatDec == (x)) || \
+ (RtcDataFormatBcd == (x)))
+
+/*!< Parameter valid check for time second */
+#define IS_VALID_TIME_SECOND(x) ((x) <= 59u)
+
+/*!< Parameter valid check for time minute */
+#define IS_VALID_TIME_MINUTE(x) ((x) <= 59u)
+
+/*!< Parameter valid check for time hour */
+#define IS_VALID_TIME_HOUR12(x) (((x) >= 1u) && ((x) <= 12u))
+#define IS_VALID_TIME_HOUR24(x) ((x) <= 23u)
+
+/*!< Parameter valid check for date weekday */
+#define IS_VALID_DATE_WEEKDAY(x) ((x) <= 6u)
+
+/*!< Parameter valid check for date day */
+#define IS_VALID_DATE_DAY(x) (((x) >= 1u) && ((x) <= 31u))
+
+/*!< Parameter valid check for date month */
+#define IS_VALID_DATE_MONTH(x) (((x) >= 1u) && ((x) <= 12u))
+
+/*!< Parameter valid check for date year */
+#define IS_VALID_DATE_YEAR(x) ((x) <= 99u)
+
+/*!< Parameter valid check for hour12 am/pm */
+#define IS_VALID_HOUR12_AMPM(x) \
+( (RtcHour12Am == (x)) || \
+ (RtcHour12Pm == (x)))
+
+/*!< Parameter valid check for alarm weekday */
+#define IS_VALID_ALARM_WEEKDAY(x) (((x) >= 1u) && ((x) <= 0x7Fu))
+
+/*!< Parameter valid check for interrupt request type */
+#define IS_VALID_IRQ_TYPE(x) \
+( (RtcIrqPeriod == (x)) || \
+ (RtcIrqAlarm == (x)))
+
+/*!< 12 hour format am/pm status bit */
+#define RTC_HOUR12_AMPM_MASK (0x20u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief De-Initialize RTC
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorTimeout De-Initialize timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_DeInit(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = Ok;
+
+ M4_RTC->CR0_f.RESET = 0u;
+ /* Waiting for normal count status or end of RTC software reset */
+ u32Timeout = SystemCoreClock >> 8u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR0_f.RESET;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
+
+ if (1u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ /* Initialize all RTC registers */
+ M4_RTC->CR0_f.RESET = 1u;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize RTC
+ **
+ ** \param [in] pstcRtcInit Pointer to RTC init configuration
+ ** \arg See the struct #stc_rtc_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t RTC_Init(const stc_rtc_init_t *pstcRtcInit)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcRtcInit)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CLK_SOURCE_TYPE(pstcRtcInit->enClkSource));
+ DDL_ASSERT(IS_VALID_PERIOD_INT_CONDITION(pstcRtcInit->enPeriodInt));
+ DDL_ASSERT(IS_VALID_TIME_FORMAT(pstcRtcInit->enTimeFormat));
+ DDL_ASSERT(IS_VALID_COMPEN_WAY(pstcRtcInit->enCompenWay));
+ DDL_ASSERT(IS_VALID_COMPEN_VALUE_RANGE(pstcRtcInit->u16CompenVal));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcRtcInit->enCompenEn));
+
+ /* Configure clock */
+ if (RtcClkLrc == pstcRtcInit->enClkSource)
+ {
+ M4_RTC->CR3_f.LRCEN = 1u;
+ }
+ M4_RTC->CR3_f.RCKSEL = pstcRtcInit->enClkSource;
+
+ /* Configure control register */
+ M4_RTC->CR1_f.PRDS = pstcRtcInit->enPeriodInt;
+ M4_RTC->CR1_f.AMPM = pstcRtcInit->enTimeFormat;
+ M4_RTC->CR1_f.ONEHZSEL = pstcRtcInit->enCompenWay;
+
+ /* Configure clock error compensation register */
+ M4_RTC->ERRCRH_f.COMP8 = ((uint32_t)pstcRtcInit->u16CompenVal >> 8u) & 0x01u;
+ M4_RTC->ERRCRL = (uint32_t)pstcRtcInit->u16CompenVal & 0x00FFu;
+ M4_RTC->ERRCRH_f.COMPEN = pstcRtcInit->enCompenEn;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enter RTC read/write mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorTimeout Enter mode timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_EnterRwMode(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = Ok;
+
+ /* Mode switch when RTC is running */
+ if (0u != M4_RTC->CR1_f.START)
+ {
+ M4_RTC->CR2_f.RWREQ = 1u;
+ /* Waiting for RWEN bit set */
+ u32Timeout = SystemCoreClock >> 8u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 0u));
+
+ if (0u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Exit RTC read/write mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorTimeout Exit mode timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_ExitRwMode(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = Ok;
+
+ /* Mode switch when RTC is running */
+ if (0u != M4_RTC->CR1_f.START)
+ {
+ M4_RTC->CR2_f.RWREQ = 0u;
+ /* Waiting for RWEN bit reset */
+ u32Timeout = SystemCoreClock >> 8u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
+
+ if (1u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC count
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC count
+ ** \arg Enable Enable RTC count
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_Cmd(en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_RTC->CR1_f.START = enNewSta;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief RTC period interrupt config
+ **
+ ** \param [in] enIntType Period interrupt request type
+ ** \arg RtcPeriodIntInvalid Period interrupt invalid
+ ** \arg RtcPeriodIntHalfSec 0.5 second period interrupt
+ ** \arg RtcPeriodIntOneSec 1 second period interrupt
+ ** \arg RtcPeriodIntOneMin 1 minute period interrupt
+ ** \arg RtcPeriodIntOneHour 1 hour period interrupt
+ ** \arg RtcPeriodIntOneDay 1 day period interrupt
+ ** \arg RtcPeriodIntOneMon 1 month period interrupt
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_PeriodIntConfig(en_rtc_period_int_type_t enIntType)
+{
+ uint8_t u8RtcSta;
+ uint8_t u8IntSta;
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PERIOD_INT_CONDITION(enIntType));
+
+ u8RtcSta = (uint8_t)M4_RTC->CR1_f.START;
+ u8IntSta = (uint8_t)M4_RTC->CR2_f.PRDIE;
+ /* Disable period interrupt when START=1 and PRDIE=1 */
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR2_f.PRDIE = 0u;
+ }
+ M4_RTC->CR1_f.PRDS = enIntType;
+
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR2_f.PRDIE = 1u;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief RTC switch to low power mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidMode RTC count not start
+ ** \retval ErrorTimeout Switch timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_LowPowerSwitch(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = ErrorInvalidMode;
+
+ /* Check RTC work status */
+ if (0u != M4_RTC->CR1_f.START)
+ {
+ M4_RTC->CR2_f.RWREQ = 1u;
+ /* Waiting for RTC RWEN bit set */
+ u32Timeout = SystemCoreClock / 100u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 0u));
+
+ if (0u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ M4_RTC->CR2_f.RWREQ = 0u;
+ /* Waiting for RTC RWEN bit reset */
+ u32TimeCnt = 0u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
+
+ if (1u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ enRet = Ok;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set RTC 1hz output compensation value
+ **
+ ** \param [in] u16CompenVal Clock compensation value
+ ** \arg 0~0x1FF
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_SetClkCompenValue(uint16_t u16CompenVal)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_COMPEN_VALUE_RANGE(u16CompenVal));
+
+ M4_RTC->ERRCRH_f.COMP8 = ((uint32_t)u16CompenVal >> 8u) & 0x01u;
+ M4_RTC->ERRCRL = (uint32_t)u16CompenVal & 0x00FFu;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable clock compensation
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC clock compensation
+ ** \arg Enable Enable RTC clock compensation
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_ClkCompenCmd(en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_RTC->ERRCRH_f.COMPEN = enNewSta;
+
+ return enRet;
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC 1hz output
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC 1hz output
+ ** \arg Enable Enable RTC 1hz output
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_OneHzOutputCmd(en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_RTC->CR1_f.ONEHZOE = enNewSta;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set RTC current date and time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [in] pstcRtcDateTime Pointer to RTC date and time configuration
+ ** \arg See the struct #stc_rtc_date_time_t
+ **
+ ** \param [in] enUpdateDateEn The function new state(Contain year/month/day/weekday)
+ ** \arg Disable Disable update RTC date
+ ** \arg Enable Enable update RTC date
+ **
+ ** \param [in] enUpdateTimeEn The function new state(Contain hour/minute/second)
+ ** \arg Disable Disable update RTC time
+ ** \arg Enable Enable update RTC time
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Enter or exit read/write mode failed
+ ** \retval ErrorInvalidParameter Parameter enUpdateDateEn or enUpdateTimeEn invalid
+ **
+ ******************************************************************************/
+en_result_t RTC_SetDateTime(en_rtc_data_format_t enFormat, const stc_rtc_date_time_t *pstcRtcDateTime,
+ en_functional_state_t enUpdateDateEn, en_functional_state_t enUpdateTimeEn)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enUpdateDateEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enUpdateTimeEn));
+
+ /* Check update status */
+ if (((Disable == enUpdateDateEn) && (Disable == enUpdateTimeEn)) || (NULL == pstcRtcDateTime))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ /* Check the date parameters */
+ if (Enable == enUpdateDateEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ DDL_ASSERT(IS_VALID_DATE_YEAR(pstcRtcDateTime->u8Year));
+ DDL_ASSERT(IS_VALID_DATE_MONTH(pstcRtcDateTime->u8Month));
+ DDL_ASSERT(IS_VALID_DATE_DAY(pstcRtcDateTime->u8Day));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_DATE_YEAR(BCD2DEC(pstcRtcDateTime->u8Year)));
+ DDL_ASSERT(IS_VALID_DATE_MONTH(BCD2DEC(pstcRtcDateTime->u8Month)));
+ DDL_ASSERT(IS_VALID_DATE_DAY(BCD2DEC(pstcRtcDateTime->u8Day)));
+ }
+ DDL_ASSERT(IS_VALID_DATE_WEEKDAY(pstcRtcDateTime->u8Weekday));
+ }
+ /* Check the time parameters */
+ if (Enable == enUpdateTimeEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(pstcRtcDateTime->u8Hour));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcDateTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(pstcRtcDateTime->u8Hour));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(pstcRtcDateTime->u8Minute));
+ DDL_ASSERT(IS_VALID_TIME_SECOND(pstcRtcDateTime->u8Second));
+ }
+ else
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(BCD2DEC(pstcRtcDateTime->u8Hour)));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcDateTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(BCD2DEC(pstcRtcDateTime->u8Hour)));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(BCD2DEC(pstcRtcDateTime->u8Minute)));
+ DDL_ASSERT(IS_VALID_TIME_SECOND(BCD2DEC(pstcRtcDateTime->u8Second)));
+ }
+ }
+
+ /* Enter read/write mode */
+ if (RTC_EnterRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Update date */
+ if (Enable == enUpdateDateEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ M4_RTC->YEAR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Year);
+ M4_RTC->MON = DEC2BCD((uint32_t)pstcRtcDateTime->u8Month);
+ M4_RTC->DAY = DEC2BCD((uint32_t)pstcRtcDateTime->u8Day);
+ }
+ else
+ {
+ M4_RTC->YEAR = pstcRtcDateTime->u8Year;
+ M4_RTC->MON = pstcRtcDateTime->u8Month;
+ M4_RTC->DAY = pstcRtcDateTime->u8Day;
+ }
+ M4_RTC->WEEK = pstcRtcDateTime->u8Weekday;
+ }
+ /* Update time */
+ if (Enable == enUpdateTimeEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcDateTime->enAmPm))
+ {
+ M4_RTC->HOUR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Hour) | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->HOUR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Hour);
+ }
+ M4_RTC->MIN = DEC2BCD((uint32_t)pstcRtcDateTime->u8Minute);
+ M4_RTC->SEC = DEC2BCD((uint32_t)pstcRtcDateTime->u8Second);
+ }
+ else
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcDateTime->enAmPm))
+ {
+ M4_RTC->HOUR = (uint32_t)pstcRtcDateTime->u8Hour | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->HOUR = (uint32_t)pstcRtcDateTime->u8Hour;
+ }
+ M4_RTC->MIN = pstcRtcDateTime->u8Minute;
+ M4_RTC->SEC = pstcRtcDateTime->u8Second;
+ }
+ }
+ /* Exit read/write mode */
+ if (RTC_ExitRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get RTC current date and time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [out] pstcRtcDateTime Pointer to RTC date and time configuration
+ ** \arg See the struct #stc_rtc_date_time_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Enter or exit read/write mode failed
+ **
+ ******************************************************************************/
+en_result_t RTC_GetDateTime(en_rtc_data_format_t enFormat, stc_rtc_date_time_t *pstcRtcDateTime)
+{
+ en_result_t enRet = Ok;
+
+ if(NULL == pstcRtcDateTime)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+
+ /* Enter read/write mode */
+ if (RTC_EnterRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Get RTC date and time registers */
+ pstcRtcDateTime->u8Year = (uint8_t)(M4_RTC->YEAR);
+ pstcRtcDateTime->u8Month = (uint8_t)(M4_RTC->MON);
+ pstcRtcDateTime->u8Day = (uint8_t)(M4_RTC->DAY);
+ pstcRtcDateTime->u8Weekday = (uint8_t)(M4_RTC->WEEK);
+ pstcRtcDateTime->u8Hour = (uint8_t)(M4_RTC->HOUR);
+ pstcRtcDateTime->u8Minute = (uint8_t)(M4_RTC->MIN);
+ pstcRtcDateTime->u8Second = (uint8_t)(M4_RTC->SEC);
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ if (RTC_HOUR12_AMPM_MASK == (pstcRtcDateTime->u8Hour & RTC_HOUR12_AMPM_MASK))
+ {
+ pstcRtcDateTime->u8Hour &= (uint8_t)(~RTC_HOUR12_AMPM_MASK);
+ pstcRtcDateTime->enAmPm = RtcHour12Pm;
+ }
+ else
+ {
+ pstcRtcDateTime->enAmPm = RtcHour12Am;
+ }
+ }
+
+ /* Check decimal format*/
+ if (RtcDataFormatDec == enFormat)
+ {
+ pstcRtcDateTime->u8Year = BCD2DEC(pstcRtcDateTime->u8Year);
+ pstcRtcDateTime->u8Month = BCD2DEC(pstcRtcDateTime->u8Month);
+ pstcRtcDateTime->u8Day = BCD2DEC(pstcRtcDateTime->u8Day);
+ pstcRtcDateTime->u8Hour = BCD2DEC(pstcRtcDateTime->u8Hour);
+ pstcRtcDateTime->u8Minute = BCD2DEC(pstcRtcDateTime->u8Minute);
+ pstcRtcDateTime->u8Second = BCD2DEC(pstcRtcDateTime->u8Second);
+ }
+
+ /* exit read/write mode */
+ if (RTC_ExitRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set RTC alarm time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [in] pstcRtcAlarmTime Pointer to RTC alarm time configuration
+ ** \arg See the struct #stc_rtc_alarm_time_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t RTC_SetAlarmTime(en_rtc_data_format_t enFormat, const stc_rtc_alarm_time_t *pstcRtcAlarmTime)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcRtcAlarmTime)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+
+ if (RtcDataFormatDec == enFormat)
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(pstcRtcAlarmTime->u8Hour));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcAlarmTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(pstcRtcAlarmTime->u8Hour));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(pstcRtcAlarmTime->u8Minute));
+ }
+ else
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(BCD2DEC(pstcRtcAlarmTime->u8Hour)));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcAlarmTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(BCD2DEC(pstcRtcAlarmTime->u8Hour)));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(BCD2DEC(pstcRtcAlarmTime->u8Minute)));
+ }
+ DDL_ASSERT(IS_VALID_ALARM_WEEKDAY(pstcRtcAlarmTime->u8Weekday));
+
+ /* Configure alarm registers */
+ if (RtcDataFormatDec == enFormat)
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcAlarmTime->enAmPm))
+ {
+ M4_RTC->ALMHOUR = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Hour) | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->ALMHOUR = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Hour);
+ }
+ M4_RTC->ALMMIN = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Minute);
+ }
+ else
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcAlarmTime->enAmPm))
+ {
+ M4_RTC->ALMHOUR = (uint32_t)pstcRtcAlarmTime->u8Hour | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->ALMHOUR = (uint32_t)pstcRtcAlarmTime->u8Hour;
+ }
+ M4_RTC->ALMMIN = pstcRtcAlarmTime->u8Minute;
+ }
+ M4_RTC->ALMWEEK = pstcRtcAlarmTime->u8Weekday;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get RTC alarm time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [out] pstcRtcAlarmTime Pointer to RTC alarm time configuration
+ ** \arg See the struct #stc_rtc_alarm_time_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t RTC_GetAlarmTime(en_rtc_data_format_t enFormat, stc_rtc_alarm_time_t *pstcRtcAlarmTime)
+{
+ en_result_t enRet = Ok;
+
+ if(NULL == pstcRtcAlarmTime)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+
+ /* Get RTC date and time register */
+ pstcRtcAlarmTime->u8Weekday = (uint8_t)M4_RTC->ALMWEEK;
+ pstcRtcAlarmTime->u8Minute = (uint8_t)M4_RTC->ALMMIN;
+ pstcRtcAlarmTime->u8Hour = (uint8_t)M4_RTC->ALMHOUR;
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ if ((pstcRtcAlarmTime->u8Hour & RTC_HOUR12_AMPM_MASK) == RTC_HOUR12_AMPM_MASK)
+ {
+ pstcRtcAlarmTime->u8Hour &= (uint8_t)(~RTC_HOUR12_AMPM_MASK);
+ pstcRtcAlarmTime->enAmPm = RtcHour12Pm;
+ }
+ else
+ {
+ pstcRtcAlarmTime->enAmPm = RtcHour12Am;
+ }
+ }
+
+ /* Check decimal format*/
+ if (RtcDataFormatDec == enFormat)
+ {
+ pstcRtcAlarmTime->u8Hour = BCD2DEC(pstcRtcAlarmTime->u8Hour);
+ pstcRtcAlarmTime->u8Minute = BCD2DEC(pstcRtcAlarmTime->u8Minute);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC alarm function
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC alarm function
+ ** \arg Enable Enable RTC alarm function
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_AlarmCmd(en_functional_state_t enNewSta)
+{
+ uint8_t u8RtcSta;
+ uint8_t u8IntSta;
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ u8RtcSta = (uint8_t)M4_RTC->CR1_f.START;
+ u8IntSta = (uint8_t)M4_RTC->CR2_f.ALMIE;
+ /* Disable alarm interrupt and clear alarm flag when START=1 and ALMIE=1 */
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR2_f.ALMIE = 0u;
+ }
+ M4_RTC->CR2_f.ALME = enNewSta;
+
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR1_f.ALMFCLR = 0u;
+ M4_RTC->CR2_f.ALMIE = u8IntSta;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC interrupt request
+ **
+ ** \param [in] enIrq RTC interrupt request type
+ ** \arg RtcIrqPeriod Period count interrupt request
+ ** \arg RtcIrqAlarm Alarm interrupt request
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable interrupt request
+ ** \arg Enable Enable interrupt request
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_IrqCmd(en_rtc_irq_type_t enIrq, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_IRQ_TYPE(enIrq));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ /* enable/disable interrupt */
+ switch (enIrq)
+ {
+ case RtcIrqPeriod:
+ M4_RTC->CR2_f.PRDIE = enNewSta;
+ break;
+ case RtcIrqAlarm:
+ M4_RTC->CR2_f.ALMIE = enNewSta;
+ break;
+ default:
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get RTC Alarm flag status
+ **
+ ** \param [in] None
+ **
+ ** \retval Set Flag is set
+ ** \retval Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t RTC_GetAlarmFlag(void)
+{
+ return (en_flag_status_t)(M4_RTC->CR2_f.ALMF);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear RTC Alarm flag status
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_ClearAlarmFlag(void)
+{
+ en_result_t enRet = Ok;
+
+ M4_RTC->CR1_f.ALMFCLR = 0u;
+
+ return enRet;
+}
+
+//@} // RtcGroup
+
+/******************************************************************************
+ * EOF (not truncated)
+ *****************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_sdioc.c b/lib/hc32f460/driver/src/hc32f460_sdioc.c new file mode 100644 index 00000000..5697202a --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_sdioc.c @@ -0,0 +1,2217 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_sdioc.c
+ **
+ ** A detailed description is available at
+ ** @link SdiocGroup SDIOC description @endlink
+ **
+ ** - 2018-11-11 CDT First version for Device Driver Library of SDIOC.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_sdioc.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup SdiocGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief SDIOC internal data
+ **
+ ******************************************************************************/
+typedef struct stc_sdioc_intern_data
+{
+ stc_sdioc_normal_irq_cb_t stcNormalIrqCb; ///< Normal irq callback function structure
+
+ stc_sdioc_error_irq_cb_t stcErrorIrqCb; ///< Error irq callback function structure
+} stc_sdioc_intern_data_t;
+
+/**
+ *******************************************************************************
+ ** \brief SDIOC instance data
+ **
+ ******************************************************************************/
+typedef struct stc_sdioc_instance_data
+{
+ const M4_SDIOC_TypeDef *SDIOCx; ///< pointer to registers of an instance
+
+ stc_sdioc_intern_data_t stcInternData; ///< module internal data of instance
+} stc_sdioc_instance_data_t;
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter valid check for SDIOC Instances. */
+#define IS_VALID_SDIOC(__SDIOCx__) \
+( (M4_SDIOC1 == (__SDIOCx__)) || \
+ (M4_SDIOC2 == (__SDIOCx__)))
+
+/*!< Parameter valid check for SDIOC mode. */
+#define IS_VALID_SDIOC_MODE(x) \
+( (SdiocModeSD == (x)) || \
+ (SdiocModeMMC == (x)))
+
+/*!< Parameter valid check for SDIOC Response Register. */
+#define IS_VALID_SDIOC_RESP(x) \
+( (SdiocRegResp01 == (x)) || \
+ (SdiocRegResp23 == (x)) || \
+ (SdiocRegResp45 == (x)) || \
+ (SdiocRegResp67 == (x)))
+
+/*!< Parameter valid check for SDIOC bus width. */
+#define IS_VALID_SDIOC_BUS_WIDTH(x) \
+( (SdiocBusWidth1Bit == (x)) || \
+ (SdiocBusWidth4Bit == (x)) || \
+ (SdiocBusWidth8Bit == (x)))
+
+/*!< Parameter valid check for SDIOC speed mode. */
+#define IS_VALID_SDIOC_SPEED_MODE(x) \
+( (SdiocHighSpeedMode == (x)) || \
+ (SdiocNormalSpeedMode == (x)))
+
+/*!< Parameter valid check for SDIOC Clock division. */
+#define IS_VALID_SDIOC_CLK_DIV(x) \
+( (SdiocClkDiv_1 == (x)) || \
+ (SdiocClkDiv_2 == (x)) || \
+ (SdiocClkDiv_4 == (x)) || \
+ (SdiocClkDiv_8 == (x)) || \
+ (SdiocClkDiv_16 == (x)) || \
+ (SdiocClkDiv_32 == (x)) || \
+ (SdiocClkDiv_64 == (x)) || \
+ (SdiocClkDiv_128 == (x)) || \
+ (SdiocClkDiv_256 == (x)))
+
+/*!< Parameter valid check for SDIOC command type. */
+#define IS_VALID_SDIOC_CMD_TYPE(x) \
+( (SdiocCmdAbort == (x)) || \
+ (SdiocCmdResume == (x)) || \
+ (SdiocCmdNormal == (x)) || \
+ (SdiocCmdSuspend == (x)))
+
+/*!< Parameter valid check for SDIOC data transfer direction. */
+#define IS_VALID_SDIOC_TRANSFER_DIR(x) \
+( (SdiocTransferToCard == (x)) || \
+ (SdiocTransferToHost == (x)))
+
+/*!< Parameter valid check for SDIOC software reset type. */
+#define IS_VALID_SDIOC_SWRESETTYPE(x) \
+( (SdiocSwResetAll == (x)) || \
+ (SdiocSwResetCmdLine == (x)) || \
+ (SdiocSwResetDatLine == (x)))
+
+/*!< Parameter valid check for SDIOC data transfer mode. */
+#define IS_VALID_SDIOC_TRANSFER_MODE(x) \
+( (SdiocTransferSingle == (x)) || \
+ (SdiocTransferInfinite == (x)) || \
+ (SdiocTransferMultiple == (x)) || \
+ (SdiocTransferStopMultiple == (x)))
+
+/*!< Parameter valid check for SDIOC data timeout. */
+#define IS_VALID_SDIOC_DATA_TIMEOUT(x) \
+( (SdiocDtoSdclk_2_13 == (x)) || \
+ (SdiocDtoSdclk_2_14 == (x)) || \
+ (SdiocDtoSdclk_2_15 == (x)) || \
+ (SdiocDtoSdclk_2_16 == (x)) || \
+ (SdiocDtoSdclk_2_17 == (x)) || \
+ (SdiocDtoSdclk_2_18 == (x)) || \
+ (SdiocDtoSdclk_2_19 == (x)) || \
+ (SdiocDtoSdclk_2_20 == (x)) || \
+ (SdiocDtoSdclk_2_21 == (x)) || \
+ (SdiocDtoSdclk_2_22 == (x)) || \
+ (SdiocDtoSdclk_2_23 == (x)) || \
+ (SdiocDtoSdclk_2_24 == (x)) || \
+ (SdiocDtoSdclk_2_25 == (x)) || \
+ (SdiocDtoSdclk_2_26 == (x)) || \
+ (SdiocDtoSdclk_2_27 == (x)))
+
+/*!< Parameter valid check for SDIOC Response type name. */
+#define IS_VALID_SDIOC_RESP_TYPE_NAME(x) \
+( (SdiocCmdRspR1 == (x)) || \
+ (SdiocCmdRspR1b == (x)) || \
+ (SdiocCmdRspR2 == (x)) || \
+ (SdiocCmdRspR3 == (x)) || \
+ (SdiocCmdRspR4 == (x)) || \
+ (SdiocCmdRspR5 == (x)) || \
+ (SdiocCmdRspR5b == (x)) || \
+ (SdiocCmdRspR6 == (x)) || \
+ (SdiocCmdRspR7 == (x)) || \
+ (SdiocCmdNoRsp == (x)))
+
+/*!< Parameter valid check for SDIOC data timeout. */
+#define IS_VALID_SDIOC_HOST_STATUS(x) \
+( (SdiocCmdPinLvl == (x)) || \
+ (SdiocData0PinLvl == (x)) || \
+ (SdiocData1PinLvl == (x)) || \
+ (SdiocData2PinLvl == (x)) || \
+ (SdiocData3PinLvl == (x)) || \
+ (SdiocCardInserted == (x)) || \
+ (SdiocDataLineActive == (x)) || \
+ (SdiocCardStateStable == (x)) || \
+ (SdiocBufferReadEnble == (x)) || \
+ (SdiocBufferWriteEnble == (x)) || \
+ (SdiocCardDetectPinLvl == (x)) || \
+ (SdiocCommandInhibitCmd == (x)) || \
+ (SdiocWriteProtectPinLvl == (x)) || \
+ (SdiocCommandInhibitData == (x)) || \
+ (SdiocReadTransferActive == (x)) || \
+ (SdiocWriteTransferActive == (x)))
+
+/*!< Parameter valid check for SDIOC normal interrupt. */
+#define IS_VALID_SDIOC_NOR_INT(x) \
+( (SdiocCardInt == (x)) || \
+ (SdiocErrorInt == (x)) || \
+ (SdiocCardRemoval == (x)) || \
+ (SdiocBlockGapEvent == (x)) || \
+ (SdiocCardInsertedInt == (x)) || \
+ (SdiocCommandComplete == (x)) || \
+ (SdiocBufferReadReady == (x)) || \
+ (SdiocBufferWriteReady == (x)) || \
+ (SdiocTransferComplete == (x)))
+
+/*!< Parameter valid check for SDIOC error interrupt. */
+#define IS_VALID_SDIOC_ERR_INT(x) \
+( (SdiocCmdCrcErr == (x)) || \
+ (SdiocDataCrcErr == (x)) || \
+ (SdiocCmdIndexErr == (x)) || \
+ (SdiocCmdEndBitErr == (x)) || \
+ (SdiocAutoCmd12Err == (x)) || \
+ (SdiocCmdTimeoutErr == (x)) || \
+ (SdiocDataEndBitErr == (x)) || \
+ (SdiocDataTimeoutErr == (x)))
+
+/*!< Parameter valid check for SDIOC auto CMD12 error status. */
+#define IS_VALID_SDIOC_AUTOCMD_ERR(x) \
+( (SdiocCmdNotIssuedErr == (x)) || \
+ (SdiocAutoCmd12CrcErr == (x)) || \
+ (SdiocAutoCmd12Timeout == (x)) || \
+ (SdiocAutoCmd12IndexErr == (x)) || \
+ (SdiocAutoCmd12EndBitErr == (x)) || \
+ (SdiocAutoCmd12NotExecuted == (x)))
+
+/*!< Parameter valid check for SDIOC detect card signal. */
+#define IS_VALID_SDIOC_DETECT_SIG(x) \
+( (SdiocSdcdPinLevel == (x)) || \
+ (SdiocCardDetectTestLevel == (x)))
+
+/*!< Parameter valid check for SDIOC data block count value. */
+#define IS_VALID_SDIOC_BLKCNT(x) ((x) != 0u)
+
+/*!< Parameter valid check for SDIOC data block size value. */
+#define IS_VALID_SDIOC_BLKSIZE(x) (!((x) & 0xF000ul))
+
+/*!< Parameter valid check for SDIOC command value. */
+#define IS_VALID_SDIOC_CMD_VAL(x) (!(0xC0u & (x)))
+
+/*!< Parameter valid check for buffer address. */
+#define IS_VALID_TRANSFER_BUF_ALIGN(x) (!((SDIOC_BUF_ALIGN_SIZE-1ul) & ((uint32_t)(x))))
+
+/*!< Parameter valid check for SDIOC command value. */
+#define IS_VALID_TRANSFER_BUF_LEN(x) (!((SDIOC_BUF_ALIGN_SIZE-1ul) & ((uint32_t)(x))))
+
+/*!< SDIOC unit max count value. */
+#define SDIOC_UNIT_MAX_CNT (ARRAY_SZ(m_astcSdiocInstanceDataLut))
+
+/*!< SDIOC default sdclk frequency. */
+#define SDIOC_SDCLK_400K (400000ul)
+
+/*!< Get the specified register address of the specified SDIOC unit */
+#define SDIOC_ARG01(__SDIOCx__) ((uint32_t)(&((__SDIOCx__)->ARG0)))
+#define SDIOC_BUF01(__SDIOCx__) ((uint32_t)(&((__SDIOCx__)->BUF0)))
+#define SDIOC_RESPx(__SDIOCx__, RESP_REG) ((uint32_t)(&((__SDIOCx__)->RESP0)) + (uint32_t)(RESP_REG))
+
+/* SDIOC buffer align size */
+#define SDIOC_BUF_ALIGN_SIZE (4ul)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+static en_sdioc_clk_div_t SdiocGetClkDiv(uint32_t u32Exclk,
+ uint32_t u32SdiocClkFreq);
+static stc_sdioc_intern_data_t* SdiocGetInternDataPtr(const M4_SDIOC_TypeDef *SDIOCx);
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Get SDIOC clock division.
+ **
+ ** \param [in] u32Exclk Exclk frequency
+ ** \param [in] u32ClkFreq SDIOC clock frequency
+ **
+ ** \retval SdiocClkDiv_1 EXCLK/1
+ ** \retval SdiocClkDiv_2 EXCLK/2
+ ** \retval SdiocClkDiv_4 EXCLK/4
+ ** \retval SdiocClkDiv_8 EXCLK/8
+ ** \retval SdiocClkDiv_16 EXCLK/16
+ ** \retval SdiocClkDiv_32 EXCLK/32
+ ** \retval SdiocClkDiv_64 EXCLK/64
+ ** \retval SdiocClkDiv_128 EXCLK/128
+ ** \retval SdiocClkDiv_256 EXCLK/256
+ **
+ ******************************************************************************/
+static en_sdioc_clk_div_t SdiocGetClkDiv(uint32_t u32Exclk,
+ uint32_t u32ClkFreq)
+{
+ uint32_t u32SdClkDiv = 0ul;
+ en_sdioc_clk_div_t enClockDiv = SdiocClkDiv_256;
+
+ if(0ul != u32ClkFreq)
+ {
+ u32SdClkDiv = u32Exclk / u32ClkFreq;
+ if (u32Exclk % u32ClkFreq)
+ {
+ u32SdClkDiv++;
+ }
+
+ if ((128ul < u32SdClkDiv) && (u32SdClkDiv <= 256ul))
+ {
+ enClockDiv = SdiocClkDiv_256;
+ }
+ else if ((64ul < u32SdClkDiv) && (u32SdClkDiv <= 128ul))
+ {
+ enClockDiv = SdiocClkDiv_128;
+ }
+ else if ((32ul < u32SdClkDiv) && (u32SdClkDiv <= 64ul))
+ {
+ enClockDiv = SdiocClkDiv_64;
+ }
+ else if ((16ul < u32SdClkDiv) && (u32SdClkDiv <= 32ul))
+ {
+ enClockDiv = SdiocClkDiv_32;
+ }
+ else if ((16ul < u32SdClkDiv) && (u32SdClkDiv <= 32ul))
+ {
+ enClockDiv = SdiocClkDiv_32;
+ }
+ else if ((8ul < u32SdClkDiv) && (u32SdClkDiv <= 16ul))
+ {
+ enClockDiv = SdiocClkDiv_16;
+ }
+ else if ((4ul < u32SdClkDiv) && (u32SdClkDiv <= 8ul))
+ {
+ enClockDiv = SdiocClkDiv_8;
+ }
+ else if ((2ul < u32SdClkDiv) && (u32SdClkDiv <= 4ul))
+ {
+ enClockDiv = SdiocClkDiv_4;
+ }
+ else if ((1ul < u32SdClkDiv) && (u32SdClkDiv <= 2ul))
+ {
+ enClockDiv = SdiocClkDiv_2;
+ }
+ else
+ {
+ enClockDiv = SdiocClkDiv_1;
+ }
+ }
+
+ return enClockDiv;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Return the internal data for a certain SDIOC instance.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval Pointer to internal data or NULL if instance is not enabled (or not known)
+ **
+ ******************************************************************************/
+static stc_sdioc_intern_data_t* SdiocGetInternDataPtr(const M4_SDIOC_TypeDef *SDIOCx)
+{
+ uint8_t i;
+ stc_sdioc_intern_data_t *pstcInternData = NULL;
+ static stc_sdioc_instance_data_t m_astcSdiocInstanceDataLut[2];
+
+ m_astcSdiocInstanceDataLut[0].SDIOCx = M4_SDIOC1;
+ m_astcSdiocInstanceDataLut[1].SDIOCx = M4_SDIOC2;
+
+ if (NULL != SDIOCx)
+ {
+ for (i = 0u; i < SDIOC_UNIT_MAX_CNT; i++)
+ {
+ if (SDIOCx == m_astcSdiocInstanceDataLut[i].SDIOCx)
+ {
+ pstcInternData = &m_astcSdiocInstanceDataLut[i].stcInternData;
+ break;
+ }
+ }
+ }
+
+ return pstcInternData;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SDIOC instance interrupt service routine
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void SDIOC_IrqHandler(M4_SDIOC_TypeDef *SDIOCx)
+{
+ stc_sdioc_intern_data_t *pstcSdiocInternData = SdiocGetInternDataPtr(SDIOCx);
+
+ /* Check for NULL pointer */
+ if (NULL != pstcSdiocInternData)
+ {
+ /**************** Normal interrupt handler ****************/
+ if (1u == SDIOCx->NORINTST_f.CC) /* Command complete */
+ {
+ SDIOCx->NORINTST_f.CC = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->NORINTST_f.TC) /* Transfer complete */
+ {
+ SDIOCx->NORINTST_f.TC = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->NORINTST_f.BGE) /* Block gap event */
+ {
+ SDIOCx->NORINTST_f.BGE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->NORINTST_f.BWR) /* Buffer write ready */
+ {
+ SDIOCx->NORINTST_f.BWR = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->NORINTST_f.BRR) /* Buffer read ready */
+ {
+ SDIOCx->NORINTST_f.BRR = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->NORINTST_f.CIST) /* Card insertion */
+ {
+ SDIOCx->NORINTST_f.CIST = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->NORINTST_f.CRM) /* Card removal */
+ {
+ SDIOCx->NORINTST_f.CRM = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->NORINTST_f.CINT) /* Card interrupt */
+ {
+ if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb();
+ }
+ }
+
+ /**************** Error interrupt handler ****************/
+ if (1u == SDIOCx->ERRINTST_f.CTOE) /* Command timeout error */
+ {
+ SDIOCx->ERRINTST_f.CTOE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->ERRINTST_f.CCE) /* Command CRC error */
+ {
+ SDIOCx->ERRINTST_f.CCE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->ERRINTST_f.CEBE) /* Command end bit error */
+ {
+ SDIOCx->ERRINTST_f.CEBE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->ERRINTST_f.CIE) /* Command index error */
+ {
+ SDIOCx->ERRINTST_f.CIE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->ERRINTST_f.DTOE) /* Data timeout error */
+ {
+ SDIOCx->ERRINTST_f.DTOE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->ERRINTST_f.DEBE) /* Data end bit error */
+ {
+ SDIOCx->ERRINTST_f.DEBE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->ERRINTST_f.DCE) /* Data CRC error */
+ {
+ SDIOCx->ERRINTST_f.DCE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb();
+ }
+ }
+
+ if (1u == SDIOCx->ERRINTST_f.ACE) /* Auto CMD12 error */
+ {
+ SDIOCx->ERRINTST_f.ACE = 1u; /* Clear interrupt flag */
+ if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb();
+ }
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initializes a SDIOC.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] pstcInitCfg Pointer to SDIOC configure structure
+ ** \arg This parameter detail refer @ref stc_sdioc_init_t
+ **
+ ** \retval Ok SDIOC initialized normally
+ ** \retval ErrorTimeout SDIOCx reset timeout
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SDIOCx is invalid
+ ** - pstcInitCfg == NULL
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t SDIOC_Init(M4_SDIOC_TypeDef *SDIOCx,
+ const stc_sdioc_init_t *pstcInitCfg)
+{
+ __IO uint32_t i = 0ul;
+ uint32_t u32Exclk = 0ul;
+ uint32_t u32Cnt = SystemCoreClock / 100ul;
+ en_result_t enRet = ErrorInvalidParameter;
+ stc_sdioc_intern_data_t *pstcSdiocInternData = NULL;
+
+ /* Get pointer to internal data structure. */
+ pstcSdiocInternData = SdiocGetInternDataPtr(SDIOCx);
+ if (NULL != pstcSdiocInternData) /* Check for instance available or not */
+ {
+ /* Reset all */
+ SDIOCx->SFTRST_f.RSTA = 1u;
+ while (0u != SDIOCx->SFTRST_f.RSTA) /* Wait until reset finish */
+ {
+ if (i++ > u32Cnt)
+ {
+ break;
+ }
+ }
+
+ if (i < u32Cnt)
+ {
+ /* Get EXCLK frequency */
+ u32Exclk = SystemCoreClock / (1ul << M4_SYSREG->CMU_SCFGR_f.EXCKS);
+
+ SDIOCx->CLKCON_f.FS = SdiocGetClkDiv(u32Exclk, SdiocClk400K);
+ SDIOCx->CLKCON_f.CE = (uint16_t)1u;
+ SDIOCx->CLKCON_f.ICE = (uint16_t)1u;
+ SDIOCx->PWRCON_f.PWON = (uint8_t)1u; /* Power on */
+
+ /* Enable all status */
+ SDIOCx->ERRINTST = (uint16_t)0x017Fu; /* Clear Error interrupt status */
+ SDIOCx->ERRINTSTEN = (uint16_t)0x017Fu; /* Enable Error interrupt status */
+ SDIOCx->NORINTST = (uint16_t)0x00F7u; /* Clear Normal interrupt status */
+ SDIOCx->NORINTSTEN = (uint16_t)0x01F7u; /* Enable Normal interrupt status */
+
+ /* Enable normal interrupt signal */
+ if (NULL != pstcInitCfg)
+ {
+ if (NULL != pstcInitCfg->pstcNormalIrqEn)
+ {
+ SDIOCx->NORINTSGEN = pstcInitCfg->pstcNormalIrqEn->u16NormalIntsgEn;
+ }
+
+ /* Set normal interrupt callback functions */
+ if (NULL != pstcInitCfg->pstcNormalIrqCb)
+ {
+ pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCommandCompleteIrqCb;
+ pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnTransferCompleteIrqCb;
+ pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnBlockGapIrqCb;
+ pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnBufferWriteReadyIrqCb;
+ pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnBufferReadReadyIrqCb;
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCardInsertIrqCb;
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCardRemovalIrqCb;
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCardIrqCb;
+ }
+
+ /* Enable error interrupt signal */
+ if (NULL != pstcInitCfg->pstcErrorIrqEn)
+ {
+ SDIOCx->ERRINTSGEN = pstcInitCfg->pstcErrorIrqEn->u16ErrorIntsgEn;
+ }
+
+ /* Set error interrupt callback functions */
+ if (NULL != pstcInitCfg->pstcErrorIrqCb)
+ {
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdTimeoutErrIrqCb;
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdCrcErrIrqCb;
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdEndBitErrIrqCb;
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdIndexErrIrqCb;
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnDataTimeoutErrIrqCb;
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnDataEndBitErrIrqCb;
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnDataCrcErrIrqCb;
+ pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnAutoCmdErrIrqCb;
+ }
+ }
+ enRet = Ok;
+ }
+ else
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initializes the specified SDIOC unit.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval Ok De-Initialize successfully.
+ ** \retval ErrorTimeout SDIOCx reset timeout.
+ ** \retval ErrorInvalidParameter SDIOCx is invalid.
+ **
+ ******************************************************************************/
+en_result_t SDIOC_DeInit(M4_SDIOC_TypeDef *SDIOCx)
+{
+ __IO uint32_t i = 0ul;
+ uint32_t u32Cnt = SystemCoreClock / 100ul;
+ en_result_t enRet = ErrorInvalidParameter;
+ stc_sdioc_intern_data_t *pstcSdiocInternData = NULL;
+
+ /* Get pointer to internal data structure. */
+ pstcSdiocInternData = SdiocGetInternDataPtr(SDIOCx);
+ if (NULL != pstcSdiocInternData) /* Check for instance available or not */
+ {
+ /* Reset all */
+ SDIOCx->SFTRST_f.RSTA = 1u;
+ while (0u != SDIOCx->SFTRST_f.RSTA) /* Wait until reset finish */
+ {
+ if (i++ > u32Cnt)
+ {
+ break;
+ }
+ }
+
+ if (i < u32Cnt)
+ {
+ /* Set normal interrupt callback functions */
+ pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb = NULL;
+ pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb = NULL;
+ pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb = NULL;
+ pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb = NULL;
+ pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb = NULL;
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb = NULL;
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb = NULL;
+ pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb = NULL;
+
+ /* Set error interrupt callback functions */
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb = NULL;
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb = NULL;
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb = NULL;
+ pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb = NULL;
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb = NULL;
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb = NULL;
+ pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb = NULL;
+ pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb = NULL;
+ enRet = Ok;
+ }
+ else
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ * @brief Set SDIOC mode.
+ * @param [in] SDIOCx Pointer to SDIOC instance register base
+ * This parameter can be one of the following values:
+ * @arg M4_SDIOC1: SDIOC unit 1 instance register base
+ * @arg M4_SDIOC2: SDIOC unit 2 instance register base
+ * @param [in] enMode SDIOCx mode
+ * @arg SdiocModeSD: SD mode
+ * @arg SdiocModeMMC: MMC mode
+ */
+void SDIOC_SetMode(const M4_SDIOC_TypeDef *SDIOCx, en_sdioc_mode_t enMode)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+ DDL_ASSERT(IS_VALID_SDIOC_MODE(enMode));
+
+ if (M4_SDIOC1 == SDIOCx)
+ {
+ M4_PERIC->SDIOC_SYCTLREG_f.SELMMC1 = (uint32_t)enMode;
+ }
+ else
+ {
+ M4_PERIC->SDIOC_SYCTLREG_f.SELMMC2 = (uint32_t)enMode;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Send SD command
+ **
+ ** This function sends command on CMD line
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] pstcCmdCfg Pointer to command transfer configuration structure.
+ ** \arg This parameter detail refer @ref stc_sdioc_cmd_cfg_t
+ **
+ ** \retval Ok Command sent normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SDIOCx is invalid
+ ** - pstcCmdCfg == NULL
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SendCommand(M4_SDIOC_TypeDef *SDIOCx,
+ const stc_sdioc_cmd_cfg_t *pstcCmdCfg)
+{
+ uint32_t u32Addr;
+ stc_sdioc_cmd_field_t stcCmdField;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for NULL pointer */
+ if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pstcCmdCfg))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_CMD_VAL(pstcCmdCfg->u8CmdIndex));
+ DDL_ASSERT(IS_VALID_SDIOC_CMD_TYPE(pstcCmdCfg->enCmdType));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCmdCfg->enDataPresentEnable));
+ DDL_ASSERT(IS_VALID_SDIOC_RESP_TYPE_NAME(pstcCmdCfg->enRspIndex));
+
+ enRet = Ok;
+ switch (pstcCmdCfg->enRspIndex)
+ {
+ case SdiocCmdNoRsp:
+ stcCmdField.RESTYP = SdiocResponseNoneBit;
+ stcCmdField.CCE = 0u;
+ stcCmdField.ICE = 0u;
+ break;
+ case SdiocCmdRspR2:
+ stcCmdField.RESTYP = SdiocResponse136Bit;
+ stcCmdField.CCE = 1u;
+ stcCmdField.ICE = 0u;
+ break;
+ case SdiocCmdRspR3:
+ case SdiocCmdRspR4:
+ stcCmdField.RESTYP = SdiocResponse48Bit;
+ stcCmdField.CCE = 0u;
+ stcCmdField.ICE = 0u;
+ break;
+ case SdiocCmdRspR1:
+ case SdiocCmdRspR5:
+ case SdiocCmdRspR6:
+ case SdiocCmdRspR7:
+ stcCmdField.RESTYP = SdiocResponse48Bit;
+ stcCmdField.CCE = 1u;
+ stcCmdField.ICE = 1u;
+ break;
+ case SdiocCmdRspR1b:
+ case SdiocCmdRspR5b:
+ stcCmdField.RESTYP = SdiocResponse48BitCheckBusy;
+ stcCmdField.CCE = 1u;
+ stcCmdField.ICE = 1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ if (enRet == Ok)
+ {
+ stcCmdField.RESERVED2 = (uint16_t)0u;
+ stcCmdField.TYP = (uint16_t)pstcCmdCfg->enCmdType;
+ stcCmdField.IDX = (uint16_t)pstcCmdCfg->u8CmdIndex;
+ stcCmdField.DAT = (uint16_t)(pstcCmdCfg->enDataPresentEnable);
+
+ u32Addr = SDIOC_ARG01(SDIOCx);
+ *(__IO uint32_t *)u32Addr = pstcCmdCfg->u32Argument;
+
+ u32Addr = (uint32_t)&stcCmdField;
+ SDIOCx->CMD = *(uint16_t *)u32Addr;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the response received from the card for the last command
+ **
+ ** This function sends command on CMD line
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enRespReg Response Specifies the SDIOC response register.
+ ** \arg SdiocRegResp01 Response0 and Response1 Register
+ ** \arg SdiocRegResp23 Response2 and Response3 Register
+ ** \arg SdiocRegResp45 Response4 and Response5 Register
+ ** \arg SdiocRegResp67 Response6 and Response7 Register
+ **
+ ** \retval The Corresponding response register value
+ **
+ ******************************************************************************/
+uint32_t SDIOC_GetResponse(const M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_response_reg_t enRespReg)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+ DDL_ASSERT(IS_VALID_SDIOC_RESP(enRespReg));
+
+ return *(__IO uint32_t *)SDIOC_RESPx(SDIOCx, enRespReg) ;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read data from SDIOCx data buffer
+ **
+ ** This function reads 32-bit data from data buffer
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] au8Data Buffer which will store SDIOC_BUFFER data
+ ** \param [in] u32Len Data length
+ **
+ ** \retval Ok Data is read normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SDIOCx is invalid
+ ** - pu32Data == NULL
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ReadBuffer(M4_SDIOC_TypeDef *SDIOCx,
+ uint8_t au8Data[],
+ uint32_t u32Len)
+{
+ uint32_t i = 0ul;
+ uint32_t u32Temp = 0ul;;
+ __IO uint32_t *SDIO_BUF_REG = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx && pu8Data pointer */
+ if ((NULL != au8Data) && \
+ (IS_VALID_SDIOC(SDIOCx)) && \
+ (IS_VALID_TRANSFER_BUF_LEN(u32Len)))
+ {
+ SDIO_BUF_REG = (__IO uint32_t *)SDIOC_BUF01(SDIOCx);
+
+ while (i < u32Len)
+ {
+ u32Temp = *SDIO_BUF_REG;
+ au8Data[i++] = (uint8_t)((u32Temp >> 0ul) & 0x000000FF);
+ au8Data[i++] = (uint8_t)((u32Temp >> 8ul) & 0x000000FF);
+ au8Data[i++] = (uint8_t)((u32Temp >> 16ul) & 0x000000FF);
+ au8Data[i++] = (uint8_t)((u32Temp >> 24ul) & 0x000000FF);
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write data to SDIOCx data buffer
+ **
+ ** This function writes 32-bit data to data buffer
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] au8Data Buffer which will be wrote to SDIOC_BUFFER
+ ** \param [in] u32Len Data length
+ **
+ ** \retval Ok Data is written normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SDIOCx is invalid
+ ** - pu8Data == NULL
+ **
+ ******************************************************************************/
+en_result_t SDIOC_WriteBuffer(M4_SDIOC_TypeDef *SDIOCx,
+ uint8_t au8Data[],
+ uint32_t u32Len)
+{
+ uint32_t i = 0ul;
+ uint32_t u32Temp = 0ul;
+ __IO uint32_t *SDIO_BUF_REG = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx && pu8Data pointer */
+ if ((NULL != au8Data) && \
+ (IS_VALID_SDIOC(SDIOCx)) && \
+ (IS_VALID_TRANSFER_BUF_LEN(u32Len)))
+ {
+ SDIO_BUF_REG = (__IO uint32_t *)SDIOC_BUF01(SDIOCx);
+
+ while (i < u32Len)
+ {
+ u32Temp = (((uint32_t)au8Data[i++]) << 0ul) & 0x000000FFul;
+ u32Temp += (((uint32_t)au8Data[i++]) << 8ul) & 0x0000FF00ul;
+ u32Temp += (((uint32_t)au8Data[i++]) << 16ul) & 0x00FF0000ul;
+ u32Temp += (((uint32_t)au8Data[i++]) << 24ul) & 0xFF000000ul;
+
+ *SDIO_BUF_REG = u32Temp;
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configure SDIOCx data parameters
+ **
+ ** This function writes 32-bit data to data buffer
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] pstcDataCfg Pointer to SDIOC data transfer configuration structure
+ ** \arg This parameter detail refer @ref stc_sdioc_data_cfg_t
+ **
+ ** \retval Ok configure normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SDIOCx is invalid
+ ** - pstcDataCfg == NULL
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ConfigData(M4_SDIOC_TypeDef *SDIOCx,
+ const stc_sdioc_data_cfg_t *pstcDataCfg)
+{
+ uint16_t u16BlkCnt = (uint16_t)0;
+ uint32_t u32Addr;
+ stc_sdioc_transmode_field_t stcTransModeField = {0};
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx && pstcDataCfg pointer */
+ if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pstcDataCfg))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_BLKCNT(pstcDataCfg->u16BlkCnt));
+ DDL_ASSERT(IS_VALID_SDIOC_BLKSIZE(pstcDataCfg->u16BlkSize));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcDataCfg->enAutoCmd12Enable));
+ DDL_ASSERT(IS_VALID_SDIOC_DATA_TIMEOUT(pstcDataCfg->enDataTimeOut));
+ DDL_ASSERT(IS_VALID_SDIOC_TRANSFER_DIR(pstcDataCfg->enTransferDir));
+ DDL_ASSERT(IS_VALID_SDIOC_TRANSFER_MODE(pstcDataCfg->enTransferMode));
+
+ enRet = Ok;
+
+ switch (pstcDataCfg->enTransferMode)
+ {
+ case SdiocTransferSingle:
+ stcTransModeField.MULB = 0u;
+ stcTransModeField.BCE = 0u;
+ break;
+ case SdiocTransferInfinite:
+ stcTransModeField.MULB = 1u;
+ stcTransModeField.BCE = 0u;
+ break;
+ case SdiocTransferMultiple:
+ u16BlkCnt = pstcDataCfg->u16BlkCnt;
+ stcTransModeField.MULB = 1u;
+ stcTransModeField.BCE = 1u;
+ break;
+ case SdiocTransferStopMultiple:
+ stcTransModeField.MULB = 1u;
+ stcTransModeField.BCE = 1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ if (enRet == Ok)
+ {
+ stcTransModeField.RESERVED0 = (uint16_t)0u;
+ stcTransModeField.DDIR = (uint16_t)(pstcDataCfg->enTransferDir);
+ stcTransModeField.ATCEN = (uint16_t)(pstcDataCfg->enAutoCmd12Enable);
+
+ /* Set the SDIOC Data Transfer Timeout value */
+ SDIOCx->TOUTCON = (uint8_t)(pstcDataCfg->enDataTimeOut);
+ /* Set the SDIOC Block Count value */
+ SDIOCx->BLKCNT = u16BlkCnt;
+ /* Set the SDIOC Block Size value */
+ SDIOCx->BLKSIZE = pstcDataCfg->u16BlkSize;
+ /* Set the SDIOC Data Transfer Mode */
+ u32Addr = (uint32_t)&stcTransModeField;
+ SDIOCx->TRANSMODE = *(uint16_t *)u32Addr;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable SDCLK output
+ **
+ ** SD host drives SDCLK line.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enCmd The SDCLK functional state command
+ ** \arg Enable Enable SDCLK function
+ ** \arg Disable Disable SDCLK function
+ **
+ ** \retval Ok SDCLK output of SDIOCx enabled normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SdclkCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ SDIOCx->CLKCON_f.CE = (uint16_t)(enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the clock division of SD clock
+ **
+ ** This function changes the SD clock division.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enClkDiv SDIOC clock division value
+ ** \arg SdiocClkDiv_1 EXCLK/1
+ ** \arg SdiocClkDiv_2 EXCLK/2
+ ** \arg SdiocClkDiv_4 EXCLK/4
+ ** \arg SdiocClkDiv_8 EXCLK/8
+ ** \arg SdiocClkDiv_16 EXCLK/16
+ ** \arg SdiocClkDiv_32 EXCLK/32
+ ** \arg SdiocClkDiv_64 EXCLK/64
+ ** \arg SdiocClkDiv_128 EXCLK/128
+ ** \arg SdiocClkDiv_256 EXCLK/256
+ **
+ ** \retval Ok SDIOC clock division is changed normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SetClkDiv(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_clk_div_t enClkDiv)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_CLK_DIV(enClkDiv));
+
+ /* Set clock division */
+ SDIOCx->CLKCON_f.FS = (uint16_t)enClkDiv;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the clock division of SD clock
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval SdiocClkDiv_1 EXCLK/1
+ ** \retval SdiocClkDiv_2 EXCLK/2
+ ** \retval SdiocClkDiv_4 EXCLK/4
+ ** \retval SdiocClkDiv_8 EXCLK/8
+ ** \retval SdiocClkDiv_16 EXCLK/16
+ ** \retval SdiocClkDiv_32 EXCLK/32
+ ** \retval SdiocClkDiv_64 EXCLK/64
+ ** \retval SdiocClkDiv_128 EXCLK/128
+ **
+ ******************************************************************************/
+en_sdioc_clk_div_t SDIOC_GetClkDiv(M4_SDIOC_TypeDef *SDIOCx)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+
+ return ((en_sdioc_clk_div_t)SDIOCx->CLKCON_f.FS);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the clock division of SD clock
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] u32ClkFreq SDIOC clock frequency
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SetClk(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ClkFreq)
+{
+ uint32_t u32Exclk = 0ul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Get EXCLK frequency */
+ u32Exclk = SystemCoreClock / (1ul << M4_SYSREG->CMU_SCFGR_f.EXCKS);
+
+ SDIOCx->CLKCON_f.CE = (uint16_t)0u;
+ SDIOCx->CLKCON_f.FS = (uint16_t)SdiocGetClkDiv(u32Exclk, u32ClkFreq);
+ SDIOCx->CLKCON_f.CE = (uint16_t)1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the bus width of SD Bus
+ **
+ ** This function changes the SD bus width.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enBusWidth Bus width
+ ** \arg SdiocBusWidth1Bit The SDIOC bus width 1 bit
+ ** \arg SdiocBusWidth4Bit The SDIOC bus width 4 bit
+ ** \arg SdiocBusWidth8Bit The SDIOC bus width 8 bit
+ **
+ ** \retval Ok Bus width is set normally
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - SDIOCx is invalid
+ ** - enBusWidth is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SetBusWidth(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_bus_width_t enBusWidth)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_BUS_WIDTH(enBusWidth));
+
+ enRet = Ok;
+
+ switch (enBusWidth)
+ {
+ case SdiocBusWidth1Bit:
+ SDIOCx->HOSTCON_f.EXDW = 0u;
+ SDIOCx->HOSTCON_f.DW = 0u;
+ break;
+ case SdiocBusWidth4Bit:
+ SDIOCx->HOSTCON_f.EXDW = 0u;
+ SDIOCx->HOSTCON_f.DW = 1u;
+ break;
+ case SdiocBusWidth8Bit:
+ SDIOCx->HOSTCON_f.EXDW = 1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the bus width of SD Bus
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval SdiocBusWidth1Bit The SDIOC bus width 1 bit
+ ** \retval SdiocBusWidth4Bit The SDIOC bus width 4 bit
+ ** \retval SdiocBusWidth8Bit The SDIOC bus width 8 bit
+ **
+ ******************************************************************************/
+en_sdioc_bus_width_t SDIOC_GetBusWidth(M4_SDIOC_TypeDef *SDIOCx)
+{
+ en_sdioc_bus_width_t enBusWidth = SdiocBusWidth4Bit;
+
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+
+ if (0u == SDIOCx->HOSTCON_f.EXDW)
+ {
+ if (0u == SDIOCx->HOSTCON_f.DW)
+ {
+ enBusWidth = SdiocBusWidth1Bit;
+ }
+ }
+ else
+ {
+ enBusWidth = SdiocBusWidth8Bit;
+ }
+
+ return enBusWidth;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the bus speed mode of SD Bus
+ **
+ ** This function changes the SD bus speed mode.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enSpeedMode Speed mode
+ ** \arg SdiocHighSpeedMode High speed mode
+ ** \arg SdiocNormalSpeedMode Normal speed mode
+ **
+ ** \retval Ok Bus speed is set normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SetSpeedMode(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_speed_mode_t enSpeedMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_SPEED_MODE(enSpeedMode));
+
+ /* Set high speed mode */
+ SDIOCx->HOSTCON_f.HSEN = ((SdiocHighSpeedMode == enSpeedMode) ? 1u : 0u);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the bus speed mode of SD Bus
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval SdiocHighSpeedMode High speed mode
+ ** \retval SdiocNormalSpeedMode Normal speed mode
+ **
+ ******************************************************************************/
+en_sdioc_speed_mode_t SDIOC_GetSpeedMode(M4_SDIOC_TypeDef *SDIOCx)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+
+ return ((SDIOCx->HOSTCON_f.HSEN) ? SdiocHighSpeedMode : SdiocNormalSpeedMode);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set data timeout counter value
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enTimeout Data timeout count value
+ ** \arg SdiocDtoSdclk_2_13 Timeout time: SDCLK*2^13
+ ** \arg SdiocDtoSdclk_2_14 Timeout time: SDCLK*2^14
+ ** \arg SdiocDtoSdclk_2_15 Timeout time: SDCLK*2^15
+ ** \arg SdiocDtoSdclk_2_16 Timeout time: SDCLK*2^16
+ ** \arg SdiocDtoSdclk_2_17 Timeout time: SDCLK*2^17
+ ** \arg SdiocDtoSdclk_2_18 Timeout time: SDCLK*2^18
+ ** \arg SdiocDtoSdclk_2_19 Timeout time: SDCLK*2^19
+ ** \arg SdiocDtoSdclk_2_20 Timeout time: SDCLK*2^20
+ ** \arg SdiocDtoSdclk_2_21 Timeout time: SDCLK*2^21
+ ** \arg SdiocDtoSdclk_2_22 Timeout time: SDCLK*2^22
+ ** \arg SdiocDtoSdclk_2_23 Timeout time: SDCLK*2^23
+ ** \arg SdiocDtoSdclk_2_24 Timeout time: SDCLK*2^24
+ ** \arg SdiocDtoSdclk_2_25 Timeout time: SDCLK*2^25
+ ** \arg SdiocDtoSdclk_2_26 Timeout time: SDCLK*2^26
+ ** \arg SdiocDtoSdclk_2_27 Timeout time: SDCLK*2^27
+ **
+ ** \retval Ok Bus speed is set normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SetDataTimeout(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_data_timeout_t enTimeout)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_DATA_TIMEOUT(enTimeout));
+
+ /* Set data timeout */
+ SDIOCx->TOUTCON_f.DTO = (uint8_t)enTimeout;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get data timeout counter value
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval SdiocDtoSdclk_2_13 Timeout time: SDCLK*2^13
+ ** \retval SdiocDtoSdclk_2_14 Timeout time: SDCLK*2^14
+ ** \retval SdiocDtoSdclk_2_15 Timeout time: SDCLK*2^15
+ ** \retval SdiocDtoSdclk_2_16 Timeout time: SDCLK*2^16
+ ** \retval SdiocDtoSdclk_2_17 Timeout time: SDCLK*2^17
+ ** \retval SdiocDtoSdclk_2_18 Timeout time: SDCLK*2^18
+ ** \retval SdiocDtoSdclk_2_19 Timeout time: SDCLK*2^19
+ ** \retval SdiocDtoSdclk_2_20 Timeout time: SDCLK*2^20
+ ** \retval SdiocDtoSdclk_2_21 Timeout time: SDCLK*2^21
+ ** \retval SdiocDtoSdclk_2_22 Timeout time: SDCLK*2^22
+ ** \retval SdiocDtoSdclk_2_23 Timeout time: SDCLK*2^23
+ ** \retval SdiocDtoSdclk_2_24 Timeout time: SDCLK*2^24
+ ** \retval SdiocDtoSdclk_2_25 Timeout time: SDCLK*2^25
+ ** \retval SdiocDtoSdclk_2_26 Timeout time: SDCLK*2^26
+ ** \retval SdiocDtoSdclk_2_27 Timeout time: SDCLK*2^27
+ **
+ ******************************************************************************/
+en_sdioc_data_timeout_t SDIOC_GetDataTimeout(M4_SDIOC_TypeDef *SDIOCx)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+
+ return (en_sdioc_data_timeout_t)(SDIOCx->TOUTCON_f.DTO);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the card detect signal
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enDetectSignal Card detect signal
+ ** \arg SdiocSdcdPinLevel SDCD# is selected (for normal use)
+ ** \arg SdiocCardDetectTestLevel The Card Detect Test Level is selected(for test purpose)
+ **
+ ** \retval Ok Set normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SetCardDetectSignal(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_detect_signal_t enDetectSignal)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_DETECT_SIG(enDetectSignal));
+ SDIOCx->HOSTCON_f.CDSS = (uint8_t)enDetectSignal;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get card inserted or not.
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval Set Card Inserted
+ ** \retval Reset No Card
+ **
+ ** \note This bit is enabled while the Card Detect Signal Selection is set to 1
+ ** and it indicates card inserted or not.
+ **
+ ******************************************************************************/
+en_flag_status_t SDIOC_GetCardDetectTestLevel(M4_SDIOC_TypeDef *SDIOCx)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+
+ return (en_flag_status_t)(SDIOCx->HOSTCON_f.CDTL);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Power on SD bus power
+ **
+ ** This function starts power supply on SD bus
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval Ok Power on normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_BusPowerOn(M4_SDIOC_TypeDef *SDIOCx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ SDIOCx->PWRCON_f.PWON = 1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Power off SD bus power
+ **
+ ** This function stops power supply on SD bus
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval Ok Power off normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_BusPowerOff(M4_SDIOC_TypeDef *SDIOCx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ SDIOCx->PWRCON_f.PWON = 0u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable the function of Stop At Block Gap Request during block gap
+ **
+ ** This function is used to stop data trasnfer of multi-block transfer
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enCmd SDIOC Stop At Block Gap Request functional state
+ ** \arg Enable Enable the function of Stop At Block Gap Request
+ ** \arg Disable Disable the function of Stop At Block Gap Request
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_StopAtBlockGapCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+ SDIOCx->BLKGPCON_f.SABGR = (uint8_t)(enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Restart data transfer
+ **
+ ** This function is used to restart data transfer when transfer is pending
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_RestartTransfer(M4_SDIOC_TypeDef *SDIOCx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ SDIOCx->BLKGPCON_f.CR = 1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable the function of Read Wait Control
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enCmd SDIOC Read Wait Control functional state
+ ** \arg Enable Enable the Read Wait Control function
+ ** \arg Disable Disable the Read Wait Control function
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ReadWaitCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+ SDIOCx->BLKGPCON_f.RWC = (uint8_t)(enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable the function of Interrupt At Block Gap
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enCmd SDIOC Interrupt At Block Gap functional state
+ ** \arg Enable Enable the function of Interrupt At Block Gap
+ ** \arg Disable Disable the function of Interrupt At Block Gap
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_InterruptAtBlockGapCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+ SDIOCx->BLKGPCON_f.IABG = (uint8_t)(enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Generate software reset to SD card
+ **
+ ** This function generates software reset all command to SD card
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enSwResetType Software reset type
+ ** \arg SdiocSwResetAll This reset affects the entire Host Controller except for the card detection circuit.
+ ** \arg SdiocSwResetCmdLine Only part of command circuit is reset.
+ ** \arg SdiocSwResetDataLine Only part of data circuit is reset.
+ **
+ ** \retval Ok Software reset is done normally
+ ** \retval ErrorTimeout SDIOCx reset timeout
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - SDIOCx is invalid
+ ** - enSwResetType is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_SoftwareReset(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_sw_reset_t enSwResetType)
+{
+ __IO uint32_t i = 0ul;
+ uint32_t u32Cnt = SystemCoreClock / 100ul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_SWRESETTYPE(enSwResetType));
+
+ enRet = Ok;
+ switch (enSwResetType)
+ {
+ case SdiocSwResetAll:
+ SDIOCx->SFTRST_f.RSTA = (uint8_t)1u;
+ while(0u != SDIOCx->SFTRST_f.RSTA) /* Wait until reset finish */
+ {
+ if (i++ > u32Cnt)
+ {
+ break;
+ }
+ }
+ break;
+ case SdiocSwResetCmdLine:
+ SDIOCx->SFTRST_f.RSTC = (uint8_t)1u;
+ while(0u != SDIOCx->SFTRST_f.RSTC) /* Wait until reset finish */
+ {
+ if (i++ > u32Cnt)
+ {
+ break;
+ }
+ }
+ break;
+ case SdiocSwResetDatLine:
+ SDIOCx->SFTRST_f.RSTD = (uint8_t)1u;
+ while(0u != SDIOCx->SFTRST_f.RSTD) /* Wait until reset finish */
+ {
+ if (i++ > u32Cnt)
+ {
+ break;
+ }
+ }
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ if (i > u32Cnt)
+ {
+ enRet = ErrorTimeout;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the status of SDIOC host controller
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enHostStatus SDIOC host status
+ ** \arg SdiocCommandInhibitCmd Command Inhibit(CMD). 1: Cannot issue command; 0:Can issue command using only CMD line
+ ** \arg SdiocCommandInhibitData Command Inhibit(DAT). 1: Cannot issue command which uses the DAT line; 0:Can issue command which uses the DAT line
+ ** \arg SdiocDataLineActive 1: DAT Line Active; 0: DAT Line Inactive
+ ** \arg SdiocWriteTransferActive Write Transfer Active.1: Transferring data; 0: No valid data
+ ** \arg SdiocReadTransferActive Read Transfer Active.1: Transferring data; 0: No valid data
+ ** \arg SdiocBufferWriteEnble 1: Write enable; 0: Write Disable
+ ** \arg SdiocBufferReadEnble 1: Read enable; 0: Read Disable
+ ** \arg SdiocCardInserted 1: Card Inserted; 0: Reset or Debouncing or No Card
+ ** \arg SdiocCardStateStable 1: No Card or Inserted; 0: Reset or Debouncing
+ ** \arg SdiocCardDetectPinLvl 1: Card present; 0: No card present
+ ** \arg SdiocWriteProtectPinLvl 1: Write enabled; 0: Write protected
+ ** \arg SdiocData0PinLvl 1: DAT0 line signal level high; 0: DAT0 line signal level low
+ ** \arg SdiocData1PinLvl 1: DAT1 line signal level high; 0: DAT1 line signal level low
+ ** \arg SdiocData2PinLvl 1: DAT2 line signal level high; 0: DAT2 line signal level low
+ ** \arg SdiocData3PinLvl 1: DAT3 line signal level high; 0: DAT3 line signal level low
+ ** \arg SdiocCmdPinLvl 1: CMD line signal level high; 0: CMD line signal level low
+ **
+ ** \retval Set The specified status is set
+ ** \retval Reset The specified status is zero
+ **
+ ******************************************************************************/
+en_flag_status_t SDIOC_GetStatus(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_host_status_t enHostStatus)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+ DDL_ASSERT(IS_VALID_SDIOC_HOST_STATUS(enHostStatus));
+
+ return ((SDIOCx->PSTAT & ((uint32_t)enHostStatus)) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable the specified signal of SDIOC normal interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enNorInt SDIOC normal interrupt
+ ** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
+ ** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
+ ** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
+ ** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
+ ** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
+ ** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
+ ** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
+ ** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
+ ** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
+ ** \param [in] enCmd SDIOC normal interrupt signal functional state
+ ** \arg Enable Enable the specified signal of SD normal interrupt
+ ** \arg Disable Disable the specified signal of SD normal interrupt
+ **
+ ** \retval Ok Set normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_NormalIrqSignalCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_nor_int_sel_t enNorInt,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+ DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
+
+ if (Enable == enCmd)
+ {
+ SDIOCx->NORINTSGEN |= (uint16_t)enNorInt;
+ }
+ else
+ {
+ SDIOCx->NORINTSGEN &= (uint16_t)(~((uint16_t)enNorInt));
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable the status of SDIOC normal interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enNorInt SDIOC normal interrupt
+ ** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
+ ** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
+ ** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
+ ** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
+ ** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
+ ** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
+ ** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
+ ** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
+ ** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
+ ** \param [in] enCmd SDIOC normal interrupt status functional state
+ ** \arg Enable Enable the specified status of SD normal interrupt
+ ** \arg Disable Disable the specified status of SD normal interrupt
+ **
+ ** \retval Ok Set normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_NormalIrqStatusCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_nor_int_sel_t enNorInt,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+ DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
+
+ if (Enable == enCmd)
+ {
+ SDIOCx->NORINTSTEN |= (uint16_t)enNorInt;
+ }
+ else
+ {
+ SDIOCx->NORINTSTEN &= (uint16_t)(~((uint16_t)enNorInt));
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the flag of SD normal interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enNorInt SDIOC normal interrupt
+ ** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
+ ** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
+ ** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
+ ** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
+ ** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
+ ** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
+ ** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
+ ** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
+ ** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
+ **
+ ** \retval Set The specified interupt flag is set
+ ** \retval Reset The specified interupt flag is zero
+ **
+ ******************************************************************************/
+en_flag_status_t SDIOC_GetNormalIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_nor_int_flag_t enNorInt)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+ DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
+
+ return ((SDIOCx->NORINTST & ((uint16_t)enNorInt)) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the flag of SD normal interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enNorInt SDIOC normal interrupt
+ ** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
+ ** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
+ ** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
+ ** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
+ ** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
+ ** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
+ ** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
+ ** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
+ ** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
+ **
+ ** \retval Ok Clear successfully.
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ClearNormalIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_nor_int_flag_t enNorInt)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
+ SDIOCx->NORINTST = (uint16_t)enNorInt;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable the signal of SD error interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enErrInt SDIOC error interrupt
+ ** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
+ ** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
+ ** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
+ ** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
+ ** \param [in] enCmd SDIOC error interrupt signal functional state
+ ** \arg Enable Enable the specified signal of SD error interrupt
+ ** \arg Disable Disable the specified signal of SD error interrupt
+ **
+ ** \retval Ok Set normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ErrIrqSignalCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_err_int_sel_t enErrInt,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ if (Enable == enCmd)
+ {
+ SDIOCx->ERRINTSGEN |= (uint16_t)enErrInt;
+ }
+ else
+ {
+ SDIOCx->ERRINTSGEN &= (uint16_t)enErrInt;
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable/Disable the status of SD error interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enErrInt SDIOC error interrupt
+ ** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
+ ** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
+ ** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
+ ** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
+ ** \param [in] enCmd SDIOC error interrupt status functional state
+ ** \arg Enable Enable the specified status of SD error interrupt
+ ** \arg Disable Disable the specified status of SD error interrupt
+ **
+ ** \retval Ok Set normally
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ErrIrqStatusCmd(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_err_int_sel_t enErrInt,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ if (Enable == enCmd)
+ {
+ SDIOCx->ERRINTSTEN |= (uint16_t)enErrInt;
+ }
+ else
+ {
+ SDIOCx->ERRINTSTEN &= (uint16_t)enErrInt;
+ }
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the flag of SD error interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enErrInt SDIOC error interrupt
+ ** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
+ ** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
+ ** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
+ ** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
+ **
+ ** \retval Set The specified interupt flag is set
+ ** \retval Reset The specified interupt flag is zero
+ **
+ ******************************************************************************/
+en_flag_status_t SDIOC_GetErrIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_err_int_flag_t enErrInt)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+ DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
+
+ return ((SDIOCx->ERRINTST & ((uint16_t)enErrInt)) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the flag of SD error interrupt
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enErrInt SDIOC error interrupt
+ ** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
+ ** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
+ ** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
+ ** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
+ **
+ ** \retval Ok Clear successfully.
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ClearErrIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_err_int_flag_t enErrInt)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
+ SDIOCx->ERRINTST = (uint16_t)enErrInt;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Force the specified error interrupt flag
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enErrInt SDIOC error interrupt
+ ** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
+ ** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
+ ** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
+ ** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
+ ** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
+ ** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ForceErrIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_err_int_sel_t enErrInt)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
+ SDIOCx->FEE |= (uint16_t)enErrInt;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the status of auto CMD12 error
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enAutoCmdErr SDIOC auto cmd error status selection
+ ** \arg SdiocAutoCmd12NotExecuted Auto CMD12 Not Executed. 1: Not executed; 0:Executed
+ ** \arg SdiocAutoCmd12Timeout Auto CMD12 Timeout Error. 1: Time out; 0:No error
+ ** \arg SdiocAutoCmd12CrcErr Auto CMD12 CRC Error. 1: CRC Error Generated; 0: No error
+ ** \arg SdiocAutoCmd12EndBitErr Auto CMD12 End Bit Error. 1: End Bit Error Generated; 0: No error to Write buffer
+ ** \arg SdiocAutoCmd12IndexErr Auto CMD12 Index Error. 1: Error; 0: No error
+ ** \arg SdiocCmdNotIssuedErr Command Not Issued By Auto CMD12 Error.1: Not Issued; 0: No error
+ **
+ ** \retval Set The specified status flag is set
+ ** \retval Reset The specified status flag is zero
+ **
+ ******************************************************************************/
+en_flag_status_t SDIOC_GetAutoCmdErrStatus(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_atuo_cmd_err_status_t enAutoCmdErr)
+{
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
+ DDL_ASSERT(IS_VALID_SDIOC_AUTOCMD_ERR(enAutoCmdErr));
+
+ return ((SDIOCx->ATCERRST & ((uint16_t)enAutoCmdErr)) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Force the specified auto CMD12 error
+ **
+ ** \param [in] SDIOCx Pointer to SDIOC instance register base
+ ** \arg M4_SDIOC1 SDIOC unit 1 instance register base
+ ** \arg M4_SDIOC2 SDIOC unit 2 instance register base
+ ** \param [in] enAutoCmdErr SDIOC auto cmd error selection
+ ** \arg SdiocAutoCmd12NotExecuted Auto CMD12 Not Executed. 1: Not executed; 0:Executed
+ ** \arg SdiocAutoCmd12Timeout Auto CMD12 Timeout Error. 1: Time out; 0:No error
+ ** \arg SdiocAutoCmd12CrcErr Auto CMD12 CRC Error. 1: CRC Error Generated; 0: No error
+ ** \arg SdiocAutoCmd12EndBitErr Auto CMD12 End Bit Error. 1: End Bit Error Generated; 0: No error to Write buffer
+ ** \arg SdiocAutoCmd12IndexErr Auto CMD12 Index Error. 1: Error; 0: No error
+ ** \arg SdiocCmdNotIssuedErr Command Not Issued By Auto CMD12 Error.1: Not Issued; 0: No error
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter SDIOCx is invalid
+ **
+ ******************************************************************************/
+en_result_t SDIOC_ForceAutoCmdErr(M4_SDIOC_TypeDef *SDIOCx,
+ en_sdioc_atuo_cmd_err_sel_t enAutoCmdErr)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for SDIOCx pointer */
+ if (IS_VALID_SDIOC(SDIOCx))
+ {
+ /* Check the parameters */
+ DDL_ASSERT(IS_VALID_SDIOC_AUTOCMD_ERR(enAutoCmdErr));
+ SDIOCx->FEA |= (uint16_t)enAutoCmdErr;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+//@} // SdiocGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_spi.c b/lib/hc32f460/driver/src/hc32f460_spi.c new file mode 100644 index 00000000..f8517098 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_spi.c @@ -0,0 +1,1133 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_spi.c
+ **
+ ** A detailed description is available at
+ ** @link SpiGroup Serial Peripheral Interface description @endlink
+ **
+ ** - 2018-10-29 CDT First version for Device Driver Library of Spi.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_spi.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup SpiGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for SPI unit */
+#define IS_VALID_SPI_UNIT(x) \
+( (M4_SPI1 == (x)) || \
+ (M4_SPI2 == (x)) || \
+ (M4_SPI3 == (x)) || \
+ (M4_SPI4 == (x)))
+
+/*!< Parameter valid check for SS setup delay option */
+#define IS_VALID_SS_SETUP_DELAY_OPTION(x) \
+( (SpiSsSetupDelayTypicalSck1 == (x)) || \
+ (SpiSsSetupDelayCustomValue == (x)))
+
+/*!< Parameter valid check for SS setup delay time */
+#define IS_VALID_SS_SETUP_DELAY_TIME(x) \
+( (SpiSsSetupDelaySck1 == (x)) || \
+ (SpiSsSetupDelaySck2 == (x)) || \
+ (SpiSsSetupDelaySck3 == (x)) || \
+ (SpiSsSetupDelaySck4 == (x)) || \
+ (SpiSsSetupDelaySck5 == (x)) || \
+ (SpiSsSetupDelaySck6 == (x)) || \
+ (SpiSsSetupDelaySck7 == (x)) || \
+ (SpiSsSetupDelaySck8 == (x)))
+
+/*!< Parameter valid check for SS hold delay time */
+#define IS_VALID_SS_HOLD_DELAY_TIME(x) \
+( (SpiSsHoldDelaySck1 == (x)) || \
+ (SpiSsHoldDelaySck2 == (x)) || \
+ (SpiSsHoldDelaySck3 == (x)) || \
+ (SpiSsHoldDelaySck4 == (x)) || \
+ (SpiSsHoldDelaySck5 == (x)) || \
+ (SpiSsHoldDelaySck6 == (x)) || \
+ (SpiSsHoldDelaySck7 == (x)) || \
+ (SpiSsHoldDelaySck8 == (x)))
+
+/*!< Parameter valid check for SS hold delay option */
+#define IS_VALID_SS_HOLD_DELAY_OPTION(x) \
+( (SpiSsHoldDelayTypicalSck1 == (x)) || \
+ (SpiSsHoldDelayCustomValue == (x)))
+
+/*!< Parameter valid check for SS interval time option */
+#define IS_VALID_SS_INTERVAL_TIME_OPTION(x) \
+( (SpiSsIntervalTypicalSck1PlusPck2 == (x)) || \
+ (SpiSsIntervalCustomValue == (x)))
+
+/*!< Parameter valid check for SS interval time */
+#define IS_VALID_SS_INTERVAL_TIME(x) \
+( (SpiSsIntervalSck1PlusPck2 == (x)) || \
+ (SpiSsIntervalSck2PlusPck2 == (x)) || \
+ (SpiSsIntervalSck3PlusPck2 == (x)) || \
+ (SpiSsIntervalSck4PlusPck2 == (x)) || \
+ (SpiSsIntervalSck5PlusPck2 == (x)) || \
+ (SpiSsIntervalSck6PlusPck2 == (x)) || \
+ (SpiSsIntervalSck7PlusPck2 == (x)) || \
+ (SpiSsIntervalSck8PlusPck2 == (x)))
+
+/*!< Parameter valid check for SS valid channel select */
+#define IS_VALID_SS_VALID_CHANNEL(x) \
+( (SpiSsValidChannel0 == (x)) || \
+ (SpiSsValidChannel1 == (x)) || \
+ (SpiSsValidChannel2 == (x)) || \
+ (SpiSsValidChannel3 == (x)))
+
+/*!< Parameter valid check for SS polarity */
+#define IS_VALID_SS_POLARITY(x) \
+( (SpiSsLowValid == (x)) || \
+ (SpiSsHighValid == (x)))
+
+/*!< Parameter valid check for read data register object */
+#define IS_VALID_READ_DATA_REG_OBJECT(x) \
+( (SpiReadReceiverBuffer == (x)) || \
+ (SpiReadSendBuffer == (x)))
+
+/*!< Parameter valid check for SCK polarity */
+#define IS_VALID_SCK_POLARITY(x) \
+( (SpiSckIdleLevelLow == (x)) || \
+ (SpiSckIdleLevelHigh == (x)))
+
+/*!< Parameter valid check for SCK phase */
+#define IS_VALID_SCK_PHASE(x) \
+( (SpiSckOddSampleEvenChange == (x)) || \
+ (SpiSckOddChangeEvenSample == (x)))
+
+/*!< Parameter valid check for clock division */
+#define IS_VALID_CLK_DIV(x) \
+( (SpiClkDiv2 == (x)) || \
+ (SpiClkDiv4 == (x)) || \
+ (SpiClkDiv8 == (x)) || \
+ (SpiClkDiv16 == (x)) || \
+ (SpiClkDiv32 == (x)) || \
+ (SpiClkDiv64 == (x)) || \
+ (SpiClkDiv128 == (x)) || \
+ (SpiClkDiv256 == (x)))
+
+/*!< Parameter valid check for data length */
+#define IS_VALID_DATA_LENGTH(x) \
+( (SpiDataLengthBit4 == (x)) || \
+ (SpiDataLengthBit5 == (x)) || \
+ (SpiDataLengthBit6 == (x)) || \
+ (SpiDataLengthBit7 == (x)) || \
+ (SpiDataLengthBit8 == (x)) || \
+ (SpiDataLengthBit9 == (x)) || \
+ (SpiDataLengthBit10 == (x)) || \
+ (SpiDataLengthBit11 == (x)) || \
+ (SpiDataLengthBit12 == (x)) || \
+ (SpiDataLengthBit13 == (x)) || \
+ (SpiDataLengthBit14 == (x)) || \
+ (SpiDataLengthBit15 == (x)) || \
+ (SpiDataLengthBit16 == (x)) || \
+ (SpiDataLengthBit20 == (x)) || \
+ (SpiDataLengthBit24 == (x)) || \
+ (SpiDataLengthBit32 == (x)))
+
+/*!< Parameter valid check for first bit position */
+#define IS_VALID_FIRST_BIT_POSITION(x) \
+( (SpiFirstBitPositionMSB == (x)) || \
+ (SpiFirstBitPositionLSB == (x)))
+
+/*!< Parameter valid check for frame number */
+#define IS_VALID_FRAME_NUMBER(x) \
+( (SpiFrameNumber1 == (x)) || \
+ (SpiFrameNumber2 == (x)) || \
+ (SpiFrameNumber3 == (x)) || \
+ (SpiFrameNumber4 == (x)))
+
+/*!< Parameter valid check for work mode */
+#define IS_VALID_WORK_MODE(x) \
+( (SpiWorkMode4Line == (x)) || \
+ (SpiWorkMode3Line == (x)))
+
+/*!< Parameter valid check for transmission mode */
+#define IS_VALID_COMM_MODE(x) \
+( (SpiTransFullDuplex == (x)) || \
+ (SpiTransOnlySend == (x)))
+
+/*!< Parameter valid check for master slave mode */
+#define IS_VALID_MASTER_SLAVE_MODE(x) \
+( (SpiModeSlave == (x)) || \
+ (SpiModeMaster == (x)))
+
+/*!< Parameter valid check for parity mode */
+#define IS_VALID_PARITY_MODE(x) \
+( (SpiParityEven == (x)) || \
+ (SpiParityOdd == (x)))
+
+/*!< Parameter valid check for SS channel */
+#define IS_VALID_SS_CHANNEL(x) \
+( (SpiSsChannel0 == (x)) || \
+ (SpiSsChannel1 == (x)) || \
+ (SpiSsChannel2 == (x)) || \
+ (SpiSsChannel3 == (x)))
+
+/*!< Parameter valid check for irq type */
+#define IS_VALID_IRQ_TYPE(x) \
+( (SpiIrqIdle == (x)) || \
+ (SpiIrqReceive == (x)) || \
+ (SpiIrqSend == (x)) || \
+ (SpiIrqError == (x)))
+
+/*!< Parameter valid check for flag type */
+#define IS_VALID_FLAG_TYPE(x) \
+( (SpiFlagReceiveBufferFull == (x)) || \
+ (SpiFlagSendBufferEmpty == (x)) || \
+ (SpiFlagUnderloadError == (x)) || \
+ (SpiFlagParityError == (x)) || \
+ (SpiFlagModeFaultError == (x)) || \
+ (SpiFlagSpiIdle == (x)) || \
+ (SpiFlagOverloadError == (x)))
+
+/*!< Parameter valid check for clear flag type */
+#define IS_VALID_CLR_FLAG_TYPE(x) \
+( (SpiFlagReceiveBufferFull == (x)) || \
+ (SpiFlagSendBufferEmpty == (x)) || \
+ (SpiFlagUnderloadError == (x)) || \
+ (SpiFlagParityError == (x)) || \
+ (SpiFlagModeFaultError == (x)) || \
+ (SpiFlagOverloadError == (x)))
+
+/*!< SPI registers reset value */
+#define SPI_REG_DR_RESET_VALUE 0x00000000ul
+#define SPI_REG_CR1_RESET_VALUE 0x00000000ul
+#define SPI_REG_CFG1_RESET_VALUE 0x00000010ul
+#define SPI_REG_SR_RESET_VALUE 0x00000020ul
+#define SPI_REG_CFG2_RESET_VALUE 0x0000031Dul
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief De-Initialize SPI unit
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_DeInit(M4_SPI_TypeDef *SPIx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint32_t regTemp = 0ul;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ regTemp = SPIx->SR;
+ if (SPI_REG_SR_RESET_VALUE != regTemp)
+ {
+ SPIx->SR = SPI_REG_SR_RESET_VALUE;
+ }
+ SPIx->CR1 = SPI_REG_CR1_RESET_VALUE;
+ SPIx->DR = SPI_REG_DR_RESET_VALUE;
+ SPIx->CFG1 = SPI_REG_CFG1_RESET_VALUE;
+ SPIx->CFG2 = SPI_REG_CFG2_RESET_VALUE;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize SPI unit
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] pstcSpiInitCfg Pointer to SPI init configuration
+ ** \arg See the struct #stc_spi_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ ** - pstcSpiInitCfg == NULL
+ **
+ ******************************************************************************/
+en_result_t SPI_Init(M4_SPI_TypeDef *SPIx, const stc_spi_init_t *pstcSpiInitCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if((IS_VALID_SPI_UNIT(SPIx)) && (NULL != pstcSpiInitCfg))
+ {
+ DDL_ASSERT(IS_VALID_SS_SETUP_DELAY_OPTION(pstcSpiInitCfg->stcDelayConfig.enSsSetupDelayOption));
+ DDL_ASSERT(IS_VALID_SS_SETUP_DELAY_TIME(pstcSpiInitCfg->stcDelayConfig.enSsSetupDelayTime));
+ DDL_ASSERT(IS_VALID_SS_HOLD_DELAY_OPTION(pstcSpiInitCfg->stcDelayConfig.enSsHoldDelayOption));
+ DDL_ASSERT(IS_VALID_SS_HOLD_DELAY_TIME(pstcSpiInitCfg->stcDelayConfig.enSsHoldDelayTime));
+ DDL_ASSERT(IS_VALID_SS_INTERVAL_TIME_OPTION(pstcSpiInitCfg->stcDelayConfig.enSsIntervalTimeOption));
+ DDL_ASSERT(IS_VALID_SS_INTERVAL_TIME(pstcSpiInitCfg->stcDelayConfig.enSsIntervalTime));
+ DDL_ASSERT(IS_VALID_SS_VALID_CHANNEL(pstcSpiInitCfg->stcSsConfig.enSsValidBit));
+ DDL_ASSERT(IS_VALID_SS_POLARITY(pstcSpiInitCfg->stcSsConfig.enSs0Polarity));
+ DDL_ASSERT(IS_VALID_SS_POLARITY(pstcSpiInitCfg->stcSsConfig.enSs1Polarity));
+ DDL_ASSERT(IS_VALID_SS_POLARITY(pstcSpiInitCfg->stcSsConfig.enSs2Polarity));
+ DDL_ASSERT(IS_VALID_SS_POLARITY(pstcSpiInitCfg->stcSsConfig.enSs3Polarity));
+ DDL_ASSERT(IS_VALID_READ_DATA_REG_OBJECT(pstcSpiInitCfg->enReadBufferObject));
+ DDL_ASSERT(IS_VALID_SCK_POLARITY(pstcSpiInitCfg->enSckPolarity));
+ DDL_ASSERT(IS_VALID_SCK_PHASE(pstcSpiInitCfg->enSckPhase));
+ DDL_ASSERT(IS_VALID_CLK_DIV(pstcSpiInitCfg->enClkDiv));
+ DDL_ASSERT(IS_VALID_DATA_LENGTH(pstcSpiInitCfg->enDataLength));
+ DDL_ASSERT(IS_VALID_FIRST_BIT_POSITION(pstcSpiInitCfg->enFirstBitPosition));
+ DDL_ASSERT(IS_VALID_FRAME_NUMBER(pstcSpiInitCfg->enFrameNumber));
+ DDL_ASSERT(IS_VALID_WORK_MODE(pstcSpiInitCfg->enWorkMode));
+ DDL_ASSERT(IS_VALID_COMM_MODE(pstcSpiInitCfg->enTransMode));
+ DDL_ASSERT(IS_VALID_MASTER_SLAVE_MODE(pstcSpiInitCfg->enMasterSlaveMode));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcSpiInitCfg->enCommAutoSuspendEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcSpiInitCfg->enModeFaultErrorDetectEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcSpiInitCfg->enParitySelfDetectEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcSpiInitCfg->enParityEn));
+ DDL_ASSERT(IS_VALID_PARITY_MODE(pstcSpiInitCfg->enParity));
+
+ /* Master mode */
+ if (SpiModeMaster == pstcSpiInitCfg->enMasterSlaveMode)
+ {
+ SPIx->CFG2_f.MSSIE = pstcSpiInitCfg->stcDelayConfig.enSsSetupDelayOption;
+ SPIx->CFG2_f.MSSDLE = pstcSpiInitCfg->stcDelayConfig.enSsHoldDelayOption;
+ SPIx->CFG2_f.MIDIE = pstcSpiInitCfg->stcDelayConfig.enSsIntervalTimeOption;
+ SPIx->CFG1_f.MSSI = pstcSpiInitCfg->stcDelayConfig.enSsSetupDelayTime;
+ SPIx->CFG1_f.MSSDL = pstcSpiInitCfg->stcDelayConfig.enSsHoldDelayTime;
+ SPIx->CFG1_f.MIDI = pstcSpiInitCfg->stcDelayConfig.enSsIntervalTime;
+ }
+ else
+ {
+ SPIx->CFG2_f.MSSIE = SpiSsSetupDelayTypicalSck1;
+ SPIx->CFG2_f.MSSDLE = SpiSsHoldDelayTypicalSck1;
+ SPIx->CFG2_f.MIDIE = SpiSsIntervalTypicalSck1PlusPck2;
+ SPIx->CFG1_f.MSSI = SpiSsSetupDelaySck1;
+ SPIx->CFG1_f.MSSDL = SpiSsHoldDelaySck1;
+ SPIx->CFG1_f.MIDI = SpiSsIntervalSck1PlusPck2;
+ }
+
+ /* 4 lines spi mode */
+ if (SpiWorkMode4Line == pstcSpiInitCfg->enWorkMode)
+ {
+ SPIx->CFG2_f.SSA = pstcSpiInitCfg->stcSsConfig.enSsValidBit;
+ SPIx->CFG1_f.SS0PV = pstcSpiInitCfg->stcSsConfig.enSs0Polarity;
+ SPIx->CFG1_f.SS1PV = pstcSpiInitCfg->stcSsConfig.enSs1Polarity;
+ SPIx->CFG1_f.SS2PV = pstcSpiInitCfg->stcSsConfig.enSs2Polarity;
+ SPIx->CFG1_f.SS3PV = pstcSpiInitCfg->stcSsConfig.enSs3Polarity;
+ }
+ else
+ {
+ SPIx->CFG2_f.SSA = SpiSsValidChannel0;
+ SPIx->CFG1_f.SS0PV = SpiSsLowValid;
+ SPIx->CFG1_f.SS1PV = SpiSsLowValid;
+ SPIx->CFG1_f.SS2PV = SpiSsLowValid;
+ SPIx->CFG1_f.SS3PV = SpiSsLowValid;
+ }
+
+ /* Configure communication config register 1 */
+ SPIx->CFG1_f.SPRDTD = pstcSpiInitCfg->enReadBufferObject;
+ SPIx->CFG1_f.FTHLV = pstcSpiInitCfg->enFrameNumber;
+
+ /* Configure communication config register 2 */
+ SPIx->CFG2_f.LSBF = pstcSpiInitCfg->enFirstBitPosition;
+ SPIx->CFG2_f.DSIZE = pstcSpiInitCfg->enDataLength;
+ SPIx->CFG2_f.MBR = pstcSpiInitCfg->enClkDiv;
+ SPIx->CFG2_f.CPOL = pstcSpiInitCfg->enSckPolarity;
+ SPIx->CFG2_f.CPHA = pstcSpiInitCfg->enSckPhase;
+
+ /* Configure control register */
+ SPIx->CR1_f.SPIMDS = pstcSpiInitCfg->enWorkMode;
+ SPIx->CR1_f.TXMDS = pstcSpiInitCfg->enTransMode;
+ SPIx->CR1_f.MSTR = pstcSpiInitCfg->enMasterSlaveMode;
+ SPIx->CR1_f.CSUSPE = pstcSpiInitCfg->enCommAutoSuspendEn;
+ SPIx->CR1_f.MODFE = pstcSpiInitCfg->enModeFaultErrorDetectEn;
+ SPIx->CR1_f.PATE = pstcSpiInitCfg->enParitySelfDetectEn;
+ SPIx->CR1_f.PAE = pstcSpiInitCfg->enParityEn;
+ SPIx->CR1_f.PAOE = pstcSpiInitCfg->enParity;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable SPI general loopback
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable general loopback
+ ** \arg Enable Enable general loopback
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_GeneralLoopbackCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ SPIx->CR1_f.SPLPBK2 = enNewSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable SPI reverse loopback
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable reverse loopback
+ ** \arg Enable Enable reverse loopback
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_ReverseLoopbackCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ SPIx->CR1_f.SPLPBK = enNewSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable SPI working
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable SPI working
+ ** \arg Enable Enable SPI working
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_Cmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ SPIx->CR1_f.SPE = enNewSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI send 8bit data or 4/5/6/7 bit data
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] u8Data Send data value
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SendData8(M4_SPI_TypeDef *SPIx, uint8_t u8Data)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ SPIx->DR = u8Data;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI send 16bit data or 9/10/11/12/13/14/15 bit data
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] u16Data Send data value
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SendData16(M4_SPI_TypeDef *SPIx, uint16_t u16Data)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ SPIx->DR = u16Data;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI send 32bit data or 20/24 bit data
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] u32Data Send data value
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SendData32(M4_SPI_TypeDef *SPIx, uint32_t u32Data)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ SPIx->DR = u32Data;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI receive 8bit data or 4/5/6/7 bit data
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \retval uint8_t Receive data value
+ **
+ ******************************************************************************/
+uint8_t SPI_ReceiveData8(const M4_SPI_TypeDef *SPIx)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx));
+
+ return ((uint8_t)SPIx->DR);
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI receive 16bit data or 9/10/11/12/13/14/15 bit data
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \retval uint16_t Receive data value
+ **
+ ******************************************************************************/
+uint16_t SPI_ReceiveData16(const M4_SPI_TypeDef *SPIx)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx));
+
+ return ((uint16_t)SPIx->DR);
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI receive 32bit data or 20/24 bit data
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \retval uint32_t Receive data value
+ **
+ ******************************************************************************/
+uint32_t SPI_ReceiveData32(const M4_SPI_TypeDef *SPIx)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx));
+
+ return ((uint32_t)SPIx->DR);
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI set SS channel valid level polarity
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enChannel Select Slave channel
+ ** \arg SpiSsChannel0 SS0 channel
+ ** \arg SpiSsChannel1 SS1 channel
+ ** \arg SpiSsChannel2 SS2 channel
+ ** \arg SpiSsChannel3 SS3 channel
+ **
+ ** \param [in] enPolarity SS channel valid level polarity
+ ** \arg SpiSsLowValid SS0~3 signal low level valid
+ ** \arg SpiSsHighValid SS0~3 signal high level valid
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SetSsPolarity(M4_SPI_TypeDef *SPIx, en_spi_ss_channel_t enChannel,
+ en_spi_ss_polarity_t enPolarity)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_SS_CHANNEL(enChannel));
+ DDL_ASSERT(IS_VALID_SS_POLARITY(enPolarity));
+
+ switch (enChannel)
+ {
+ case SpiSsChannel0:
+ SPIx->CFG1_f.SS0PV = enPolarity;
+ break;
+ case SpiSsChannel1:
+ SPIx->CFG1_f.SS1PV = enPolarity;
+ break;
+ case SpiSsChannel2:
+ SPIx->CFG1_f.SS2PV = enPolarity;
+ break;
+ case SpiSsChannel3:
+ SPIx->CFG1_f.SS3PV = enPolarity;
+ break;
+ default:
+ break;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI set SS valid channel
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enChannel Select Slave channel
+ ** \arg SpiSsChannel0 SS0 channel
+ ** \arg SpiSsChannel1 SS1 channel
+ ** \arg SpiSsChannel2 SS2 channel
+ ** \arg SpiSsChannel3 SS3 channel
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SetSsValidChannel(M4_SPI_TypeDef *SPIx, en_spi_ss_channel_t enChannel)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_SS_CHANNEL(enChannel));
+
+ SPIx->CFG2_f.SSA = enChannel;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI set read data register object
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enObject Read data register object
+ ** \arg SpiReadReceiverBuffer Read receive buffer
+ ** \arg SpiReadSendBuffer Read send buffer(must be read when TDEF=1)
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SetReadDataRegObject(M4_SPI_TypeDef *SPIx, en_spi_read_object_t enObject)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_READ_DATA_REG_OBJECT(enObject));
+
+ SPIx->CFG1_f.SPRDTD = enObject;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI set frame number
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enFrameNum Once read or write frame number
+ ** \arg SpiFrameNumber1 1 frame data
+ ** \arg SpiFrameNumber2 2 frame data
+ ** \arg SpiFrameNumber3 3 frame data
+ ** \arg SpiFrameNumber4 4 frame data
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SetFrameNumber(M4_SPI_TypeDef *SPIx, en_spi_frame_number_t enFrameNum)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_FRAME_NUMBER(enFrameNum));
+
+ SPIx->CFG1_f.FTHLV = enFrameNum;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI set data length
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enDataLength Read or write data length
+ ** \arg SpiDataLengthBit4 4 bits
+ ** \arg SpiDataLengthBit5 5 bits
+ ** \arg SpiDataLengthBit6 6 bits
+ ** \arg SpiDataLengthBit7 7 bits
+ ** \arg SpiDataLengthBit8 8 bits
+ ** \arg SpiDataLengthBit9 9 bits
+ ** \arg SpiDataLengthBit10 10 bits
+ ** \arg SpiDataLengthBit11 11 bits
+ ** \arg SpiDataLengthBit12 12 bits
+ ** \arg SpiDataLengthBit13 13 bits
+ ** \arg SpiDataLengthBit14 14 bits
+ ** \arg SpiDataLengthBit15 15 bits
+ ** \arg SpiDataLengthBit16 16 bits
+ ** \arg SpiDataLengthBit20 20 bits
+ ** \arg SpiDataLengthBit24 24 bits
+ ** \arg SpiDataLengthBit32 32 bits
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SetDataLength(M4_SPI_TypeDef *SPIx, en_spi_data_length_t enDataLength)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_DATA_LENGTH(enDataLength));
+
+ SPIx->CFG2_f.DSIZE = enDataLength;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI set first bit position
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enPosition First bit position
+ ** \arg SpiFirstBitPositionMSB Spi first bit to MSB
+ ** \arg SpiFirstBitPositionLSB Spi first bit to LSB
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SetFirstBitPosition(M4_SPI_TypeDef *SPIx, en_spi_first_bit_position_t enPosition)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_FIRST_BIT_POSITION(enPosition));
+
+ SPIx->CFG2_f.LSBF = enPosition;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SPI set clock division
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enClkDiv Clock division
+ ** \arg SpiClkDiv2 Spi pclk1 division 2
+ ** \arg SpiClkDiv4 Spi pclk1 division 4
+ ** \arg SpiClkDiv8 Spi pclk1 division 8
+ ** \arg SpiClkDiv16 Spi pclk1 division 16
+ ** \arg SpiClkDiv32 Spi pclk1 division 32
+ ** \arg SpiClkDiv64 Spi pclk1 division 64
+ ** \arg SpiClkDiv128 Spi pclk1 division 128
+ ** \arg SpiClkDiv256 Spi pclk1 division 256
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_SetClockDiv(M4_SPI_TypeDef *SPIx, en_spi_clk_div_t enClkDiv)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_CLK_DIV(enClkDiv));
+
+ SPIx->CFG2_f.MBR = enClkDiv;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable SPI interrupt request
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enIrq SPI interrupt request type
+ ** \arg SpiIrqIdle Spi idle interrupt request
+ ** \arg SpiIrqReceive Spi receive interrupt request
+ ** \arg SpiIrqSend Spi send interrupt request
+ ** \arg SpiIrqError Spi error interrupt request
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable interrupt request
+ ** \arg Enable Enable interrupt request
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_IrqCmd(M4_SPI_TypeDef *SPIx, en_spi_irq_type_t enIrq,
+ en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_IRQ_TYPE(enIrq));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ switch (enIrq)
+ {
+ case SpiIrqIdle:
+ SPIx->CR1_f.IDIE = enNewSta;
+ break;
+ case SpiIrqReceive:
+ SPIx->CR1_f.RXIE = enNewSta;
+ break;
+ case SpiIrqSend:
+ SPIx->CR1_f.TXIE = enNewSta;
+ break;
+ case SpiIrqError:
+ SPIx->CR1_f.EIE = enNewSta;
+ break;
+ default:
+ break;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get SPI flag status
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enFlag SPI flag type
+ ** \arg SpiFlagReceiveBufferFull Receive buffer full flag
+ ** \arg SpiFlagSendBufferEmpty Send buffer empty flag
+ ** \arg SpiFlagUnderloadError Underload error flag
+ ** \arg SpiFlagParityError Parity error flag
+ ** \arg SpiFlagModeFaultError Mode fault error flag
+ ** \arg SpiFlagSpiIdle SPI idle flag
+ ** \arg SpiFlagOverloadErro Overload error flag
+ **
+ ** \retval Set Flag is set
+ ** \retval Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t SPI_GetFlag(M4_SPI_TypeDef *SPIx, en_spi_flag_type_t enFlag)
+{
+ en_flag_status_t enFlagSta = Reset;
+
+ /* Check parameters */
+ if (IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case SpiFlagReceiveBufferFull:
+ enFlagSta = (en_flag_status_t)SPIx->SR_f.RDFF;
+ break;
+ case SpiFlagSendBufferEmpty:
+ enFlagSta = (en_flag_status_t)SPIx->SR_f.TDEF;
+ break;
+ case SpiFlagUnderloadError:
+ enFlagSta = (en_flag_status_t)SPIx->SR_f.UDRERF;
+ break;
+ case SpiFlagParityError:
+ enFlagSta = (en_flag_status_t)SPIx->SR_f.PERF;
+ break;
+ case SpiFlagModeFaultError:
+ enFlagSta = (en_flag_status_t)SPIx->SR_f.MODFERF;
+ break;
+ case SpiFlagSpiIdle:
+ enFlagSta = (en_flag_status_t)(bool)(!SPIx->SR_f.IDLNF);
+ break;
+ case SpiFlagOverloadError:
+ enFlagSta = (en_flag_status_t)SPIx->SR_f.OVRERF;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return enFlagSta;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear SPI flag status
+ **
+ ** \param [in] SPIx Pointer to SPI unit configuration address
+ ** \arg M4_SPI1 SPI unit 1 configuration Address
+ ** \arg M4_SPI2 SPI unit 2 configuration Address
+ ** \arg M4_SPI3 SPI unit 3 configuration Address
+ ** \arg M4_SPI4 SPI unit 4 configuration Address
+ **
+ ** \param [in] enFlag SPI flag type
+ ** \arg SpiFlagReceiveBufferFull Receive buffer full flag
+ ** \arg SpiFlagSendBufferEmpty Send buffer empty flag
+ ** \arg SpiFlagUnderloadError Underload error flag
+ ** \arg SpiFlagParityError Parity error flag
+ ** \arg SpiFlagModeFaultError Mode fault error flag
+ ** \arg SpiFlagOverloadErro Overload error flag
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - SPIx is invalid
+ **
+ ******************************************************************************/
+en_result_t SPI_ClearFlag(M4_SPI_TypeDef *SPIx, en_spi_flag_type_t enFlag)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SPI_UNIT(SPIx))
+ {
+ DDL_ASSERT(IS_VALID_CLR_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case SpiFlagReceiveBufferFull:
+ SPIx->SR_f.RDFF = 0u;
+ break;
+ case SpiFlagSendBufferEmpty:
+ SPIx->SR_f.TDEF = 0u;
+ break;
+ case SpiFlagUnderloadError:
+ SPIx->SR_f.UDRERF = 0u;
+ break;
+ case SpiFlagParityError:
+ SPIx->SR_f.PERF = 0u;
+ break;
+ case SpiFlagModeFaultError:
+ SPIx->SR_f.MODFERF = 0u;
+ break;
+ case SpiFlagOverloadError:
+ SPIx->SR_f.OVRERF = 0u;
+ break;
+ default:
+ break;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+//@} // SpiGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_sram.c b/lib/hc32f460/driver/src/hc32f460_sram.c new file mode 100644 index 00000000..b87e16d2 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_sram.c @@ -0,0 +1,282 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_sram.c
+ **
+ ** A detailed description is available at
+ ** @link SramGroup Internal SRAM module description @endlink
+ **
+ ** - 2018-10-17 CDT First version for Device Driver Library of SRAM.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_sram.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup SramGroup
+ ******************************************************************************/
+//@{
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*! Parameter validity check for ECC/Parity error handling. */
+#define IS_VALID_ERR_OP(x) \
+( ((x) == SramNmi) || \
+ ((x) == SramReset))
+
+/*! Parameter validity check for SRAM ECC mode */
+#define IS_VALID_ECC_MD(x) \
+( ((x) == EccMode0) || \
+ ((x) == EccMode1) || \
+ ((x) == EccMode2) || \
+ ((x) == EccMode3))
+
+/*! Parameter validity check for SRAM Index */
+#define IS_VALID_INDEX(x) \
+( ((x) == Sram12Idx) || \
+ ((x) == Sram3Idx) || \
+ ((x) == SramHsIdx) || \
+ ((x) == SramRetIdx))
+
+/*! Parameter validity check for SRAM R/W wait cycle */
+#define IS_VALID_WAIT_CYCLE(x) \
+( ((x) == SramCycle1) || \
+ ((x) == SramCycle2) || \
+ ((x) == SramCycle3) || \
+ ((x) == SramCycle4) || \
+ ((x) == SramCycle5) || \
+ ((x) == SramCycle6) || \
+ ((x) == SramCycle7) || \
+ ((x) == SramCycle8))
+
+/*! Parameter validity check for SRAM error status */
+#define IS_VALID_ERR(x) \
+( ((x) == Sram3EccErr1) || \
+ ((x) == Sram3EccErr2) || \
+ ((x) == Sram12ParityErr) || \
+ ((x) == SramHSParityErr) || \
+ ((x) == SramRetParityErr))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief SRAM read, write wait cycle register disable function
+ **
+ ** \param None
+ **
+ ** \retval Ok SRAM R/W wait cycle register disabled
+ **
+ ******************************************************************************/
+en_result_t SRAM_WT_Disable(void)
+{
+ M4_SRAMC->WTPR = 0x76u;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SRAM read, write wait cycle register enable function
+ **
+ ** \param None
+ **
+ ** \retval Ok SRAM R/W wait cycle register enabled
+ **
+ ******************************************************************************/
+en_result_t SRAM_WT_Enable(void)
+{
+ M4_SRAMC->WTPR = 0x77u;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SRAM ECC/Parity check register disable function
+ **
+ ** \param None
+ **
+ ** \retval Ok SRAM ECC/Parity check register disabled
+ **
+ ******************************************************************************/
+en_result_t SRAM_CK_Disable(void)
+{
+ M4_SRAMC->CKPR = 0x76u;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SRAM ECC/Parity check register enable function
+ **
+ ** \param None
+ **
+ ** \retval Ok SRAM ECC/Parity check register enabled
+ **
+ ******************************************************************************/
+en_result_t SRAM_CK_Enable(void)
+{
+ M4_SRAMC->CKPR = 0x77u;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get SRAM ECC/Parity error status flag
+ **
+ ** \param [in] enSramErrStatus SRAM error status, This parameter can be
+ ** some values of @ref en_sram_err_status_t
+ **
+ ** \retval Set Corresponding error occurs
+ ** Reset Corresponding error not occurs
+ **
+ ******************************************************************************/
+en_flag_status_t SRAM_GetStatus(en_sram_err_status_t enSramErrStatus)
+{
+ DDL_ASSERT(IS_VALID_ERR(enSramErrStatus));
+ if (true == !!(enSramErrStatus & M4_SRAMC->CKSR))
+ {
+ return Set;
+ }
+ else
+ {
+ return Reset;
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear SRAM ECC/Parity error status flag
+ **
+ ** \param [in] enSramErrStatus SRAM error status, This parameter can be
+ ** some values of @ref en_sram_err_status_t
+ **
+ ** \retval Ok Corresponding error flag be cleared
+ ** ErrorInvalidParameter Invalid parameter
+ **
+ ******************************************************************************/
+en_result_t SRAM_ClrStatus(en_sram_err_status_t enSramErrStatus)
+{
+ DDL_ASSERT(IS_VALID_ERR(enSramErrStatus));
+ M4_SRAMC->CKSR |= enSramErrStatus;
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SRAM initialization
+ **
+ ** \param [in] pstcSramConfig SRAM configure structure
+ **
+ ** \retval Ok SRAM initialized
+ ** ErrorInvalidParameter Invalid parameter
+ **
+ ******************************************************************************/
+en_result_t SRAM_Init(const stc_sram_config_t *pstcSramConfig)
+{
+ uint8_t i = 0u;
+ uint8_t u8TmpIdx;
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_WAIT_CYCLE(pstcSramConfig->enSramRC));
+ DDL_ASSERT(IS_VALID_WAIT_CYCLE(pstcSramConfig->enSramWC));
+ DDL_ASSERT(IS_VALID_ECC_MD(pstcSramConfig->enSramEccMode));
+ DDL_ASSERT(IS_VALID_ERR_OP(pstcSramConfig->enSramEccOp));
+ DDL_ASSERT(IS_VALID_ERR_OP(pstcSramConfig->enSramPyOp));
+
+ u8TmpIdx = pstcSramConfig->u8SramIdx;
+
+ if (0u == u8TmpIdx)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ SRAM_WT_Enable();
+ SRAM_CK_Enable();
+ for (i = 0u; i < 4u; i++)
+ {
+ if (true == (u8TmpIdx & 0x01u))
+ {
+ M4_SRAMC->WTCR |= (pstcSramConfig->enSramRC | \
+ (pstcSramConfig->enSramWC << 4ul)) << (i * 8ul);
+ }
+ u8TmpIdx >>= 1u;
+ }
+ /* SRAM3 ECC config */
+ if (pstcSramConfig->u8SramIdx & Sram3Idx)
+ {
+ M4_SRAMC->CKCR_f.ECCMOD = pstcSramConfig->enSramEccMode;
+ M4_SRAMC->CKCR_f.ECCOAD = pstcSramConfig->enSramEccOp;
+ }
+ /* SRAM1/2/HS/Ret parity config */
+ else
+ {
+ M4_SRAMC->CKCR_f.PYOAD = pstcSramConfig->enSramPyOp;
+ }
+
+ SRAM_WT_Disable();
+ SRAM_CK_Disable();
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief SRAM de-initialization
+ **
+ ** \param None
+ **
+ ** \retval Ok SRAM de-initialized
+ **
+ ******************************************************************************/
+en_result_t SRAM_DeInit(void)
+{
+ /* SRAM R/W wait register */
+ M4_SRAMC->WTPR = 0x77ul;
+ M4_SRAMC->WTCR = 0ul;
+ M4_SRAMC->WTPR = 0x76ul;
+
+ /* SRAM check register */
+ M4_SRAMC->CKPR = 0x77ul;
+ M4_SRAMC->CKCR = 0ul;
+ M4_SRAMC->CKPR = 0x76ul;
+
+ /* SRAM status register */
+ M4_SRAMC->CKSR = 0x1Ful;
+
+ return Ok;
+}
+
+//@} // SramGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_swdt.c b/lib/hc32f460/driver/src/hc32f460_swdt.c new file mode 100644 index 00000000..391193e3 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_swdt.c @@ -0,0 +1,166 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_swdt.c
+ **
+ ** A detailed description is available at
+ ** @link SwdtGroup Special Watchdog Counter description @endlink
+ **
+ ** - 2018-10-16 CDT First version for Device Driver Library of SWDT.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_swdt.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup SwdtGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for flag type */
+#define IS_VALID_FLAG_TYPE(x) \
+( (SwdtFlagCountUnderflow == (x)) || \
+ (SwdtFlagRefreshError == (x)))
+
+/*!< SWDT_RR register refresh key */
+#define SWDT_REFRESH_START_KEY ((uint16_t)0x0123)
+#define SWDT_REFRESH_END_KEY_ ((uint16_t)0x3210)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief SWDT refresh counter
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t SWDT_RefreshCounter(void)
+{
+ en_result_t enRet = Ok;
+
+ M4_SWDT->RR = SWDT_REFRESH_START_KEY;
+ M4_SWDT->RR = SWDT_REFRESH_END_KEY_;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get SWDT counter current count value
+ **
+ ** \param [in] None
+ **
+ ** \retval uint16_t SWDT counter current count value
+ **
+ ******************************************************************************/
+uint16_t SWDT_GetCountValue(void)
+{
+ return ((uint16_t)M4_SWDT->SR_f.CNT);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get SWDT flag status
+ **
+ ** \param [in] enFlag SWDT flag type
+ ** \arg SwdtFlagCountUnderflow Count underflow flag
+ ** \arg SwdtFlagRefreshError Refresh error flag
+ **
+ ** \retval Set Flag is set
+ ** \retval Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t SWDT_GetFlag(en_swdt_flag_type_t enFlag)
+{
+ en_flag_status_t enFlagSta = Reset;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case SwdtFlagCountUnderflow:
+ enFlagSta = (en_flag_status_t)M4_SWDT->SR_f.UDF;
+ break;
+ case SwdtFlagRefreshError:
+ enFlagSta = (en_flag_status_t)M4_SWDT->SR_f.REF;
+ break;
+ default:
+ break;
+ }
+
+ return enFlagSta;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear SWDT flag status
+ **
+ ** \param [in] enFlag SWDT flag type
+ ** \arg SwdtFlagCountUnderflow Count underflow flag
+ ** \arg SwdtFlagRefreshError Refresh error flag
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t SWDT_ClearFlag(en_swdt_flag_type_t enFlag)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case SwdtFlagCountUnderflow:
+ M4_SWDT->SR_f.UDF = 0u;
+ break;
+ case SwdtFlagRefreshError:
+ M4_SWDT->SR_f.REF = 0u;
+ break;
+ default:
+ break;
+ }
+
+ return enRet;
+}
+
+//@} // SwdtGroup
+
+/******************************************************************************
+ * EOF (not truncated)
+ *****************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timer0.c b/lib/hc32f460/driver/src/hc32f460_timer0.c new file mode 100644 index 00000000..7e3ef568 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timer0.c @@ -0,0 +1,963 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timer0.c
+ **
+ ** A detailed description is available at
+ ** @link Timer0Group description @endlink
+ **
+ ** - 2018-10-11 CDT First version for Device Driver Library of TIMER0.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timer0.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup Timer0Group
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/* Parameter validity check for unit. */
+#define IS_VALID_UNIT(x) \
+( ((x) == M4_TMR01) || \
+ ((x) == M4_TMR02))
+
+/* Parameter validity check for channel. */
+#define IS_VALID_CHANNEL(x) \
+( ((x) == Tim0_ChannelA) || \
+ ((x) == Tim0_ChannelB))
+
+/* Parameter validity check for command. */
+#define IS_VALID_COMMAND(x) \
+( ((x) == Disable) || \
+ ((x) == Enable))
+
+/* Parameter validity check for timer0 function mode. */
+#define IS_VALID_FUNCTION(x) \
+( ((x) == Tim0_OutputCapare) || \
+ ((x) == Tim0_InputCaptrue))
+
+/* Parameter validity check for clock division. */
+#define IS_VALID_CLK_DIVISION(x) \
+( ((x) == Tim0_ClkDiv0) || \
+ ((x) == Tim0_ClkDiv2) || \
+ ((x) == Tim0_ClkDiv4) || \
+ ((x) == Tim0_ClkDiv8) || \
+ ((x) == Tim0_ClkDiv16) || \
+ ((x) == Tim0_ClkDiv32) || \
+ ((x) == Tim0_ClkDiv64) || \
+ ((x) == Tim0_ClkDiv128) || \
+ ((x) == Tim0_ClkDiv256) || \
+ ((x) == Tim0_ClkDiv512) || \
+ ((x) == Tim0_ClkDiv1024))
+
+/* Parameter validity check for synchronous clock source. */
+#define IS_VALID_CLK_SYN_SRC(x) \
+( ((x) == Tim0_Pclk1) || \
+ ((x) == Tim0_InsideHardTrig))
+
+/* Parameter validity check for asynchronous clock source. */
+#define IS_VALID_CLK_ASYN_SRC(x) \
+( ((x) == Tim0_LRC) || \
+ ((x) == Tim0_XTAL32))
+
+/* Parameter validity check for counter clock mode. */
+#define IS_VALID_CLK_MODE(x) \
+( ((x) == Tim0_Sync) || \
+ ((x) == Tim0_Async))
+
+/* Parameter validity check for counter clock mode for M4_TMR01. */
+#define IS_VALID_CLK_MODE_UNIT01(x) \
+( (x) == Tim0_Async)
+
+/* Parameter validity check for external trigger event. */
+#define IS_VALID_TRIG_SRC_EVENT(x) \
+( ((x) <= EVT_PORT_EIRQ15) || \
+ (((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
+ (((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
+ (((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
+ (((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
+ (((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
+ (((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
+ (((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
+ (((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
+ (((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
+ (((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
+ (((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
+ (((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
+ (((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
+ (((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
+ (((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
+ (((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
+ (((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
+ (((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
+ (((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
+ (((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
+ (((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
+ (((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
+ (((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
+ (((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
+ (((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
+ ((x) == EVT_WDT_REFUDF) || \
+ (((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
+ (((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
+ (((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)))
+
+/* Parameter validity check for common trigger. */
+#define IS_VALID_TIM0_COM_TRIGGER(x) \
+( ((x) == Tim0ComTrigger_1) || \
+ ((x) == Tim0ComTrigger_2) || \
+ ((x) == Tim0ComTrigger_1_2))
+
+/* Delay count for time out */
+#define TIMER0_TMOUT (0x5000ul)
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Get clock mode
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \retval Tim0_Sync: Synchronous clock
+ ** \retval Tim0_Async: Asynchronous clock
+ **
+ ******************************************************************************/
+static en_tim0_counter_mode_t TIMER0_GetClkMode(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh)
+{
+ en_tim0_counter_mode_t enMode = Tim0_Sync;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ switch(enCh)
+ {
+ case Tim0_ChannelA:
+ enMode = (en_tim0_counter_mode_t)pstcTim0Reg->BCONR_f.SYNSA;
+ break;
+ case Tim0_ChannelB:
+ enMode = (en_tim0_counter_mode_t)pstcTim0Reg->BCONR_f.SYNSB;
+ break;
+ default:
+ break;
+ }
+ return enMode;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Time delay for register write in asynchronous mode
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \param [in] enIsPublicReg Enable for BCONR and STFLR register delay
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+static void AsyncDelay(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
+ en_functional_state_t enIsPublicReg)
+{
+ en_functional_state_t enDelayEn = Disable;
+ en_tim0_counter_mode_t enModeA = TIMER0_GetClkMode(pstcTim0Reg, Tim0_ChannelA);
+ en_tim0_counter_mode_t enModeB = TIMER0_GetClkMode(pstcTim0Reg, Tim0_ChannelB);
+
+ if(Enable == enIsPublicReg)
+ {
+ if((Tim0_Async == enModeA) || (Tim0_Async == enModeB))
+ {
+ enDelayEn = Enable;
+ }
+ }
+ else
+ {
+ if(Tim0_Async == TIMER0_GetClkMode(pstcTim0Reg, enCh))
+ {
+ enDelayEn = Enable;
+ }
+ }
+
+ if(Enable == enDelayEn)
+ {
+ for(uint32_t i=0ul; i<SystemCoreClock/10000ul; i++)
+ {
+ __NOP();
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer0 status flag
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \retval Set Flag is set
+ ** Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t TIMER0_GetFlag(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh)
+{
+ en_flag_status_t enFlag = Reset;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ switch(enCh)
+ {
+ case Tim0_ChannelA:
+ enFlag = (en_flag_status_t)pstcTim0Reg->STFLR_f.CMAF;
+ break;
+ case Tim0_ChannelB:
+ enFlag = (en_flag_status_t)pstcTim0Reg->STFLR_f.CMBF;
+ break;
+ default:
+ break;
+ }
+ return enFlag;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear Timer0 status flag
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Timer0_ChA or Timer0_ChB
+ **
+ ** \retval Ok Success
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_ClearFlag(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ if(Tim0_ChannelA == enCh)
+ {
+ pstcTim0Reg->STFLR_f.CMAF =0u;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(0u != pstcTim0Reg->STFLR_f.CMAF)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pstcTim0Reg->STFLR_f.CMBF = 0u;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(0u != pstcTim0Reg->STFLR_f.CMBF)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Command the timer0 function
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Timer0_ChA or Timer0_ChB
+ **
+ ** \param [in] enCmd Disable or Enable the function
+ **
+ ** \retval Ok Success
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_Cmd(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+ DDL_ASSERT(IS_VALID_COMMAND(enCmd));
+
+ switch (enCh)
+ {
+ case Tim0_ChannelA:
+ pstcTim0Reg->BCONR_f.CSTA = enCmd;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(enCmd != pstcTim0Reg->BCONR_f.CSTA)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ break;
+ case Tim0_ChannelB:
+ pstcTim0Reg->BCONR_f.CSTB = enCmd;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(enCmd != pstcTim0Reg->BCONR_f.CSTB)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Select the timer0 function mode
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \param [in] enFunc Timer0 function,Tim0_OutputCapare or Tim0_InputCapture
+ **
+ ** \retval Ok Success
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_SetFunc(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
+ en_tim0_function_t enFunc)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+ DDL_ASSERT(IS_VALID_FUNCTION(enFunc));
+
+ switch (enCh)
+ {
+ case Tim0_ChannelA:
+ pstcTim0Reg->BCONR_f.CAPMDA = enFunc;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(enFunc != pstcTim0Reg->BCONR_f.CAPMDA)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ break;
+ case Tim0_ChannelB:
+ pstcTim0Reg->BCONR_f.CAPMDB = enFunc;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(enFunc != pstcTim0Reg->BCONR_f.CAPMDB)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Timer0 interrupt function command
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \param [in] enCmd Disable or Enable the function
+ **
+ ** \retval Ok Success
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_IntCmd(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+ DDL_ASSERT(IS_VALID_COMMAND(enCmd));
+
+ switch (enCh)
+ {
+ case Tim0_ChannelA:
+ pstcTim0Reg->BCONR_f.INTENA = enCmd;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(enCmd != pstcTim0Reg->BCONR_f.INTENA)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ break;
+ case Tim0_ChannelB:
+ pstcTim0Reg->BCONR_f.INTENB = enCmd;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(enCmd != pstcTim0Reg->BCONR_f.INTENB)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer0 counter register
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \retval uint16_t Count register
+ **
+ ******************************************************************************/
+uint16_t TIMER0_GetCntReg(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh)
+{
+ uint16_t u16Value = 0u;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ if(Tim0_ChannelA == enCh)
+ {
+ u16Value = (uint16_t)((pstcTim0Reg->CNTAR)&0xFFFFu);
+ }
+ else
+ {
+ u16Value = (uint16_t)((pstcTim0Reg->CNTBR)&0xFFFFu);
+ }
+
+ return u16Value;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write Timer0 counter register
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \param [in] u16Cnt Data to write
+ **
+ ** \retval Ok Success
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_WriteCntReg(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh,
+ uint16_t u16Cnt)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ if(Tim0_ChannelA == enCh)
+ {
+ pstcTim0Reg->CNTAR = (uint32_t)u16Cnt;
+ AsyncDelay(pstcTim0Reg, enCh, Disable);
+ while(u16Cnt != (uint16_t)pstcTim0Reg->CNTAR)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pstcTim0Reg->CNTBR = (uint32_t)u16Cnt;
+ AsyncDelay(pstcTim0Reg, enCh, Disable);
+ while(u16Cnt != (uint16_t)pstcTim0Reg->CNTBR)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer0 base compare count register
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \retval uint16_t Base compare count register
+ **
+ ******************************************************************************/
+uint16_t TIMER0_GetCmpReg(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh)
+{
+ uint16_t u16Value = 0u;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ if(Tim0_ChannelA == enCh)
+ {
+ u16Value = (uint16_t)((pstcTim0Reg->CMPAR)&0xFFFFu);
+ }
+ else
+ {
+ u16Value = (uint16_t)((pstcTim0Reg->CMPBR)&0xFFFFu);
+ }
+ return u16Value;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Wirte Timer0 base compare count register
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \param [in] u16Cnt Data to write
+ **
+ ** \retval Ok Success
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_WriteCmpReg(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
+ uint16_t u16Cnt)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ if(Tim0_ChannelA == enCh)
+ {
+ pstcTim0Reg->CMPAR = (uint32_t)u16Cnt;
+ AsyncDelay(pstcTim0Reg, enCh, Disable);
+ while(u16Cnt != (uint16_t)pstcTim0Reg->CMPAR)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pstcTim0Reg->CMPBR = (uint32_t)u16Cnt;
+ AsyncDelay(pstcTim0Reg, enCh, Disable);
+ while(u16Cnt != (uint16_t)pstcTim0Reg->CMPBR)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Timer0 peripheral base function initialize
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \param [in] pstcBaseInit Timer0 function base parameter structure
+ **
+ ** \retval Ok Process finished.
+ ** \retval ErrorInvalidParameter Parameter error.
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_BaseInit(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh,
+ const stc_tim0_base_init_t* pstcBaseInit)
+{
+ stc_tmr0_bconr_field_t stcBconrTmp;
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+
+ if (NULL != pstcBaseInit)
+ {
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+ DDL_ASSERT(IS_VALID_CLK_DIVISION(pstcBaseInit->Tim0_ClockDivision));
+ DDL_ASSERT(IS_VALID_CLK_SYN_SRC(pstcBaseInit->Tim0_SyncClockSource));
+ DDL_ASSERT(IS_VALID_CLK_ASYN_SRC(pstcBaseInit->Tim0_AsyncClockSource));
+ DDL_ASSERT(IS_VALID_CLK_MODE(pstcBaseInit->Tim0_CounterMode));
+
+ if((M4_TMR01 == pstcTim0Reg)&&(Tim0_ChannelA == enCh))
+ {
+ DDL_ASSERT(IS_VALID_CLK_MODE_UNIT01(pstcBaseInit->Tim0_CounterMode));
+ }
+
+ /*Read current BCONR register */
+ stcBconrTmp = pstcTim0Reg->BCONR_f;
+ /* Clear current configurate CH */
+ if(Tim0_ChannelA == enCh)
+ {
+ *(uint32_t *)&stcBconrTmp &= 0xFFFF0000ul;
+ }
+ else
+ {
+ *(uint32_t *)&stcBconrTmp &= 0x0000FFFFul;
+ }
+ pstcTim0Reg->BCONR_f = stcBconrTmp;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(*(uint32_t *)&stcBconrTmp != *(uint32_t *)&(pstcTim0Reg->BCONR_f))
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+
+ switch(enCh)
+ {
+ case Tim0_ChannelA:
+
+ switch(pstcBaseInit->Tim0_CounterMode)
+ {
+ case Tim0_Sync:
+ stcBconrTmp.SYNCLKA = pstcBaseInit->Tim0_SyncClockSource;
+ break;
+ case Tim0_Async:
+ stcBconrTmp.ASYNCLKA = pstcBaseInit->Tim0_AsyncClockSource;
+ break;
+ default:
+ break;
+ }
+ /*set clock division*/
+ stcBconrTmp.CKDIVA = pstcBaseInit->Tim0_ClockDivision;
+ /* Write BCONR register */
+ pstcTim0Reg->BCONR_f = stcBconrTmp;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+
+ /*set timer compare value*/
+ pstcTim0Reg->CMPAR = pstcBaseInit->Tim0_CmpValue;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+
+ /*set timer counter mode*/
+ pstcTim0Reg->BCONR_f.SYNSA = pstcBaseInit->Tim0_CounterMode;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ u32TimeOut = 0ul;
+ while(pstcBaseInit->Tim0_CounterMode != pstcTim0Reg->BCONR_f.SYNSA)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+
+ break;
+
+ case Tim0_ChannelB:
+ switch(pstcBaseInit->Tim0_CounterMode)
+ {
+ case Tim0_Sync:
+ stcBconrTmp.SYNCLKB = pstcBaseInit->Tim0_SyncClockSource;
+ break;
+ case Tim0_Async:
+ stcBconrTmp.ASYNCLKB = pstcBaseInit->Tim0_AsyncClockSource;
+ break;
+ default:
+ break;
+ }
+ /*set clock division*/
+ stcBconrTmp.CKDIVB = pstcBaseInit->Tim0_ClockDivision;
+ /* Write BCONR register */
+ pstcTim0Reg->BCONR_f = stcBconrTmp;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+
+ /*set timer compare value*/
+ pstcTim0Reg->CMPBR = pstcBaseInit->Tim0_CmpValue;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+
+ /*set timer counter mode*/
+ pstcTim0Reg->BCONR_f.SYNSB = pstcBaseInit->Tim0_CounterMode;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ u32TimeOut = 0ul;
+ while(pstcBaseInit->Tim0_CounterMode != pstcTim0Reg->BCONR_f.SYNSB)
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Timer0 peripheral base function initalize
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \retval Ok Process finished.
+ ** \retval ErrorTimeout Process timeout
+ **
+ ******************************************************************************/
+en_result_t TIMER0_DeInit(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32TimeOut = 0ul;
+
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+
+ switch(enCh)
+ {
+ case Tim0_ChannelA:
+ pstcTim0Reg->BCONR &= 0xFFFF0000ul;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(0ul != (pstcTim0Reg->BCONR & 0x0000FFFFul))
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+
+ pstcTim0Reg->CMPAR = 0x0000FFFFul;
+ pstcTim0Reg->CNTAR = 0x00000000ul;
+ pstcTim0Reg->STFLR_f.CMAF =0u;
+ break;
+
+ case Tim0_ChannelB:
+ pstcTim0Reg->BCONR &= 0x0000FFFFul;
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+ while(0ul != (pstcTim0Reg->BCONR & 0xFFFF0000ul))
+ {
+ if(u32TimeOut++ > TIMER0_TMOUT)
+ {
+ enRet = ErrorTimeout;
+ break;
+ }
+ }
+
+ pstcTim0Reg->CMPBR = 0x0000FFFFul;
+ pstcTim0Reg->CNTBR = 0x00000000ul;
+ pstcTim0Reg->STFLR_f.CMBF =0u;
+ break;
+ default:
+ break;
+ }
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set external trigger source for Timer0
+ **
+ ** \param [in] enEvent External event source
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void TIMER0_SetTriggerSrc(en_event_src_t enEvent)
+{
+ DDL_ASSERT(IS_VALID_TRIG_SRC_EVENT(enEvent));
+
+ M4_AOS->TMR0_HTSSR_f.TRGSEL = enEvent;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timer0 common trigger.
+ **
+ ** \param [in] enComTrigger Timer0 common trigger selection. See @ref en_tim0_com_trigger_t for details.
+ ** \param [in] enState Enable or disable the specified common trigger.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void TIMER0_ComTriggerCmd(en_tim0_com_trigger_t enComTrigger, en_functional_state_t enState)
+{
+ uint32_t u32ComTrig = (uint32_t)enComTrigger;
+
+ DDL_ASSERT(IS_VALID_TIM0_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (enState == Enable)
+ {
+ M4_AOS->TMR0_HTSSR |= (u32ComTrig << 30u);
+ }
+ else
+ {
+ M4_AOS->TMR0_HTSSR &= ~(u32ComTrig << 30u);
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Timer0 hardware trigger function initalize
+ **
+ ** \param [in] pstcTim0Reg Pointer to Timer0 register
+ **
+ ** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
+ **
+ ** \param [in] pStcInit Timer0 hareware trigger function structure
+ **
+ ** \retval Ok Process finished.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t TIMER0_HardTriggerInit(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh,
+ const stc_tim0_trigger_init_t* pStcInit)
+{
+ stc_tmr0_bconr_field_t stcBconrTmp;
+ en_result_t enRet = Ok;
+
+ if(NULL != pStcInit)
+ {
+ DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
+ DDL_ASSERT(IS_VALID_CHANNEL(enCh));
+ DDL_ASSERT(IS_VALID_FUNCTION(pStcInit->Tim0_OCMode));
+ DDL_ASSERT(IS_VALID_TRIG_SRC_EVENT(pStcInit->Tim0_SelTrigSrc));
+
+ /*Read current BCONR register */
+ stcBconrTmp = pstcTim0Reg->BCONR_f;
+
+ switch(enCh)
+ {
+ case Tim0_ChannelA:
+ /*set work on input captrue or output capare*/
+ stcBconrTmp.CAPMDA = pStcInit->Tim0_OCMode;
+ /*enable input capture*/
+ stcBconrTmp.HICPA = pStcInit->Tim0_InTrigEnable;
+ /*enable trigger clear counter*/
+ stcBconrTmp.HCLEA = pStcInit->Tim0_InTrigClear;
+ /*enable trigger start counter*/
+ stcBconrTmp.HSTAA = pStcInit->Tim0_InTrigStart;
+ /*enable trigger stop counter*/
+ stcBconrTmp.HSTPA = pStcInit->Tim0_InTrigStop;
+
+ /* Write BCONR register */
+ pstcTim0Reg->BCONR_f = stcBconrTmp;
+ break;
+ case Tim0_ChannelB:
+ /*set work on input captrue or output capare*/
+ stcBconrTmp.CAPMDB = pStcInit->Tim0_OCMode;
+ /*enable input capture*/
+ stcBconrTmp.HICPB = pStcInit->Tim0_InTrigEnable;
+ /*enable trigger clear counter*/
+ stcBconrTmp.HCLEB = pStcInit->Tim0_InTrigClear;
+ /*enable trigger start counter*/
+ stcBconrTmp.HSTAB = pStcInit->Tim0_InTrigStart;
+ /*enable trigger stop counter*/
+ stcBconrTmp.HSTPB = pStcInit->Tim0_InTrigStop;
+
+ /* Write BCONR register */
+ pstcTim0Reg->BCONR_f = stcBconrTmp;
+ break;
+ default:
+ break;
+ }
+ AsyncDelay(pstcTim0Reg, enCh, Enable);
+
+ /* Set trigger source*/
+ M4_AOS->TMR0_HTSSR_f.TRGSEL = pStcInit->Tim0_SelTrigSrc;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+
+}
+
+//@} // Timer0Group
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timer4_cnt.c b/lib/hc32f460/driver/src/hc32f460_timer4_cnt.c new file mode 100644 index 00000000..ac56c071 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timer4_cnt.c @@ -0,0 +1,838 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timer4_cnt.c
+ **
+ ** A detailed description is available at
+ ** @link Timer4CntGroup Timer4CNT description @endlink
+ **
+ ** - 2018-11-02 CDT First version for Device Driver Library of Timer4CNT.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timer4_cnt.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup Timer4CntGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter validity check for Timer4 unit */
+#define IS_VALID_TIMER4(__TMRx__) \
+( (M4_TMR41 == (__TMRx__)) || \
+ (M4_TMR42 == (__TMRx__)) || \
+ (M4_TMR43 == (__TMRx__)))
+
+/*!< Parameter validity check for CNT pclk division */
+#define IS_VALID_CNT_CLK_DIV(x) \
+( (Timer4CntPclkDiv1 == (x)) || \
+ (Timer4CntPclkDiv2 == (x)) || \
+ (Timer4CntPclkDiv4 == (x)) || \
+ (Timer4CntPclkDiv8 == (x)) || \
+ (Timer4CntPclkDiv16 == (x)) || \
+ (Timer4CntPclkDiv32 == (x)) || \
+ (Timer4CntPclkDiv64 == (x)) || \
+ (Timer4CntPclkDiv128 == (x)) || \
+ (Timer4CntPclkDiv256 == (x)) || \
+ (Timer4CntPclkDiv512 == (x)) || \
+ (Timer4CntPclkDiv1024 == (x)))
+
+/*!< Parameter validity check for CNT mode */
+#define IS_VALID_CNT_MODE(x) \
+( (Timer4CntSawtoothWave == (x)) || \
+ (Timer4CntTriangularWave == (x)))
+
+/*!< Parameter validity check for CNT interrupt mask */
+#define IS_VALID_CNT_INT_MSK(x) \
+( (Timer4CntIntMask0 == (x)) || \
+ (Timer4CntIntMask1 == (x)) || \
+ (Timer4CntIntMask2 == (x)) || \
+ (Timer4CntIntMask3 == (x)) || \
+ (Timer4CntIntMask4 == (x)) || \
+ (Timer4CntIntMask5 == (x)) || \
+ (Timer4CntIntMask6 == (x)) || \
+ (Timer4CntIntMask7 == (x)) || \
+ (Timer4CntIntMask8 == (x)) || \
+ (Timer4CntIntMask9 == (x)) || \
+ (Timer4CntIntMask10 == (x)) || \
+ (Timer4CntIntMask11 == (x)) || \
+ (Timer4CntIntMask12 == (x)) || \
+ (Timer4CntIntMask13 == (x)) || \
+ (Timer4CntIntMask14 == (x)) || \
+ (Timer4CntIntMask15 == (x)))
+
+/*!< Parameter validity check for CNT match interrupt type */
+#define IS_VALID_CNT_INT_TYPE(x) \
+( (Timer4CntZeroMatchInt == (x)) || \
+ (Timer4CntPeakMatchInt == (x)))
+
+/*!< Parameter validity check for CNT clock source */
+#define IS_VALID_CNT_CLK(x) \
+( (Timer4CntPclk == (x)) || \
+ (Timer4CntExtclk == (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')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Initialize Timer4 CNT
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] pstcInitCfg Pointer to CNT initialization configuration structure
+ ** \arg This parameter detail refer @ref stc_timer4_cnt_init_t
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TMR4x is invalid
+ ** - pstcInitCfg == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_Init(M4_TMR4_TypeDef *TMR4x,
+ const stc_timer4_cnt_init_t *pstcInitCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ stc_tmr4_ccsr_field_t CCSR_f = {0};
+ stc_tmr4_cvpr_field_t CVPR_f = {0};
+
+ /* Check for TMR4x && pstcInitCfg pointer */
+ if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CNT_CLK(pstcInitCfg->enClk));
+ DDL_ASSERT(IS_VALID_CNT_MODE(pstcInitCfg->enCntMode));
+ DDL_ASSERT(IS_VALID_CNT_CLK_DIV(pstcInitCfg->enClkDiv));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enBufferCmd));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enZeroIntCmd));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enPeakIntCmd));
+ DDL_ASSERT(IS_VALID_CNT_INT_MSK(pstcInitCfg->enZeroIntMsk));
+ DDL_ASSERT(IS_VALID_CNT_INT_MSK(pstcInitCfg->enPeakIntMsk));
+
+ /* Set default value */
+ TMR4x->CCSR = (uint16_t)0x0050u;
+ TMR4x->CNTR = (uint16_t)0x0000u;
+ TMR4x->CPSR = (uint16_t)0xFFFFu;
+ TMR4x->CVPR = (uint16_t)0x0000u;
+
+ /* stop count of CNT */
+ CCSR_f.STOP = 1u;
+
+ /* set count clock div of CNT */
+ CCSR_f.CKDIV = pstcInitCfg->enClkDiv;
+
+ /* set cnt mode */
+ CCSR_f.MODE = pstcInitCfg->enCntMode;
+
+ /* set buffer enable bit */
+ CCSR_f.BUFEN = (uint16_t)(pstcInitCfg->enBufferCmd);
+
+ /* set external clock enable bit */
+ CCSR_f.ECKEN = (Timer4CntExtclk == pstcInitCfg->enClk) ? ((uint16_t)1u) : ((uint16_t)0u);
+
+ /* Set interrupt enable */
+ CCSR_f.IRQZEN = (uint16_t)(pstcInitCfg->enZeroIntCmd);
+ CCSR_f.IRQPEN = (uint16_t)(pstcInitCfg->enPeakIntCmd);
+
+ /* set intterrupt mask times */
+ CVPR_f.ZIM = (uint16_t)(pstcInitCfg->enZeroIntMsk);
+ CVPR_f.PIM = (uint16_t)(pstcInitCfg->enPeakIntMsk);
+
+ /* Set Timer4 register */
+ TMR4x->CVPR = *(uint16_t *)(&CVPR_f);
+ TMR4x->CCSR_f = CCSR_f;
+ TMR4x->CPSR = pstcInitCfg->u16Cycle;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-initialize Timer4 CNT
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Ok De-Initialize successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_DeInit(M4_TMR4_TypeDef *TMR4x)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Set default value */
+ TMR4x->CCSR = (uint16_t)0x0050u;
+ TMR4x->CNTR = (uint16_t)0x0000u;
+ TMR4x->CPSR = (uint16_t)0xFFFFu;
+ TMR4x->CVPR = (uint16_t)0x0000u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 CNT clock source
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCntClk Timer4 CNT clock source
+ ** \arg Timer4CntPclk Uses the internal clock (PCLK) as CNT's count clock.
+ ** \arg Timer4CntExtclk Uses an external input clock (EXCK) as CNT's count clock.
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_SetClock(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_clk_t enCntClk)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CNT_CLK(enCntClk));
+ /* set external clock enable bit */
+ TMR4x->CCSR_f.ECKEN = (uint16_t)(enCntClk);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 CNT clock source
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Timer4CntPclk Uses the internal clock (PCLK) as CNT's count clock.
+ ** \retval Timer4CntExtclk Uses an external input clock (EXCK) as CNT's count clock.
+ **
+ ******************************************************************************/
+en_timer4_cnt_clk_t TIMER4_CNT_GetClock(M4_TMR4_TypeDef *TMR4x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ return (en_timer4_cnt_clk_t)(TMR4x->CCSR_f.ECKEN);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 CNT clock division
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enClkDiv Timer4 CNT clock division
+ ** \arg Timer4CntPclkDiv1 Timer4 CNT clock: PCLK
+ ** \arg Timer4CntPclkDiv2 Timer4 CNT clock: PCLK/2
+ ** \arg Timer4CntPclkDiv4 Timer4 CNT clock: PCLK/4
+ ** \arg Timer4CntPclkDiv8 Timer4 CNT clock: PCLK/8
+ ** \arg Timer4CntPclkDiv16 Timer4 CNT clock: PCLK/16
+ ** \arg Timer4CntPclkDiv32 Timer4 CNT clock: PCLK/32
+ ** \arg Timer4CntPclkDiv64 Timer4 CNT clock: PCLK/64
+ ** \arg Timer4CntPclkDiv128 Timer4 CNT clock: PCLK/128
+ ** \arg Timer4CntPclkDiv256 Timer4 CNT clock: PCLK/256
+ ** \arg Timer4CntPclkDiv512 Timer4 CNT clock: PCLK/512
+ ** \arg Timer4CntPclkDiv1024 Timer4 CNT clock: PCLK/1024
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_SetClockDiv(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_clk_div_t enClkDiv)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CNT_CLK_DIV(enClkDiv));
+ TMR4x->CCSR_f.CKDIV = (uint16_t)enClkDiv;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 CNT clock division
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Timer4CntPclkDiv1 Timer4 CNT clock: PCLK
+ ** \retval Timer4CntPclkDiv2 Timer4 CNT clock: PCLK/2
+ ** \retval Timer4CntPclkDiv4 Timer4 CNT clock: PCLK/4
+ ** \retval Timer4CntPclkDiv8 Timer4 CNT clock: PCLK/8
+ ** \retval Timer4CntPclkDiv16 Timer4 CNT clock: PCLK/16
+ ** \retval Timer4CntPclkDiv32 Timer4 CNT clock: PCLK/32
+ ** \retval Timer4CntPclkDiv64 Timer4 CNT clock: PCLK/64
+ ** \retval Timer4CntPclkDiv128 Timer4 CNT clock: PCLK/128
+ ** \retval Timer4CntPclkDiv256 Timer4 CNT clock: PCLK/256
+ ** \retval Timer4CntPclkDiv512 Timer4 CNT clock: PCLK/512
+ ** \retval Timer4CntPclkDiv1024 Timer4 CNT clock: PCLK/1024
+ **
+ ******************************************************************************/
+en_timer4_cnt_clk_div_t TIMER4_CNT_GetClockDiv(M4_TMR4_TypeDef *TMR4x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ return (en_timer4_cnt_clk_div_t)(TMR4x->CCSR_f.CKDIV);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 CNT mode
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enMode Timer4 CNT mode
+ ** \arg Timer4CntSawtoothWave Timer4 count mode:sawtooth wave
+ ** \arg Timer4CntTriangularWave Timer4 count mode:triangular wave
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_SetMode(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_mode_t enMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CNT_MODE(enMode));
+ TMR4x->CCSR_f.MODE = (uint16_t)enMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 CNT mode
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Timer4CntSawtoothWave Timer4 count mode:sawtooth wave
+ ** \retval Timer4CntTriangularWave Timer4 count mode:triangular wave
+ **
+ ******************************************************************************/
+en_timer4_cnt_mode_t TIMER4_CNT_GetMode(M4_TMR4_TypeDef *TMR4x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ return (en_timer4_cnt_mode_t)(TMR4x->CCSR_f.MODE);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Start Timer4 CNT
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Ok Start successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_Start(M4_TMR4_TypeDef *TMR4x)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ TMR4x->CCSR_f.STOP = (uint16_t)0u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Stop Timer4 CNT
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Ok Stop successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_Stop(M4_TMR4_TypeDef *TMR4x)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ TMR4x->CCSR_f.STOP = (uint16_t)1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 CNT interrupt
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enIntType The specified type of Timer4 CNT interrupt
+ ** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
+ ** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
+ ** \param [in] enCmd DCU interrupt functional state
+ ** \arg Enable Enable the specified Timer4 CNT interrupt function
+ ** \arg Disable Disable the specified Timer4 CNT interrupt function
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TMR4x is invalid
+ ** - enIntType is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_IrqCmd(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_int_t enIntType,
+ en_functional_state_t enCmd)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+ DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
+
+ enRet = Ok;
+ switch (enIntType)
+ {
+ case Timer4CntZeroMatchInt:
+ TMR4x->CCSR_f.IRQZEN = (uint16_t)enCmd;
+ break;
+ case Timer4CntPeakMatchInt:
+ TMR4x->CCSR_f.IRQPEN = (uint16_t)enCmd;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 CNT interrupt flag
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enIntType Timer4 CNT interrupt type
+ ** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
+ ** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
+ **
+ ** \retval Reset None interrupt request on Timer4 CNT
+ ** \retval Set Detection interrupt request on Timer4 CNT
+ **
+ ******************************************************************************/
+en_flag_status_t TIMER4_CNT_GetIrqFlag(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_int_t enIntType)
+{
+ uint16_t u16Flag = 0u;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+ DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
+
+ switch (enIntType)
+ {
+ case Timer4CntZeroMatchInt:
+ u16Flag = TMR4x->CCSR_f.IRQZF;
+ break;
+ case Timer4CntPeakMatchInt:
+ u16Flag = TMR4x->CCSR_f.IRQPF;
+ break;
+ default:
+ break;
+ }
+
+ return (en_flag_status_t)u16Flag;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear Timer4 CNT interrupt flag
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enIntType Timer4 CNT interrupt type
+ ** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
+ ** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
+ **
+ ** \retval Ok Clear successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TMR4x is invalid
+ ** - enIntType is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_ClearIrqFlag(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_int_t enIntType)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
+
+ enRet = Ok;
+ switch (enIntType)
+ {
+ case Timer4CntZeroMatchInt:
+ TMR4x->CCSR_f.IRQZF = (uint16_t)0u;
+ break;
+ case Timer4CntPeakMatchInt:
+ TMR4x->CCSR_f.IRQPF = (uint16_t)0u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the cycle value of the specified Timer4 CNT.
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] u16Cycle The Timer4 CNT cycle value
+ ** \arg number of 16bit
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_SetCycleVal(M4_TMR4_TypeDef *TMR4x, uint16_t u16Cycle)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ TMR4x->CPSR = u16Cycle;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get the cycle value of the specified Timer4 CNT.
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval The cycle value of the specified Timer4 CNT.
+ **
+ ******************************************************************************/
+uint16_t TIMER4_CNT_GetCycleVal(const M4_TMR4_TypeDef *TMR4x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ return TMR4x->CPSR;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear Timer4 CNT register CNTR
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Ok Clear successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_ClearCountVal(M4_TMR4_TypeDef *TMR4x)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ TMR4x->CCSR_f.CLEAR = (uint16_t)1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set the current count value of the specified Timer4 CNT.
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] u16Count The Timer4 CNT current count value
+ ** \arg number of 16bit
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_SetCountVal(M4_TMR4_TypeDef *TMR4x, uint16_t u16Count)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ TMR4x->CNTR = u16Count;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 CNT current count value
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval The current count value of the specified Timer4 CNT.
+ **
+ ******************************************************************************/
+uint16_t TIMER4_CNT_GetCountVal(const M4_TMR4_TypeDef *TMR4x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ return TMR4x->CNTR;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 CNT interrupt mask times
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enIntType Timer4 CNT interrupt type
+ ** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
+ ** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
+ ** \param [in] enMaskTimes Timer4 CNT interrupt mask times
+ ** \arg Timer4CntIntMask0 CNT interrupt flag is always set(not masked) for every CNT count at "0x0000" or peak.
+ ** \arg Timer4CntIntMask1 CNT interrupt flag is set once for 2 every CNT counts at "0x0000" or peak (skiping 1 count).
+ ** \arg Timer4CntIntMask2 CNT interrupt flag is set once for 3 every CNT counts at "0x0000" or peak (skiping 2 count).
+ ** \arg Timer4CntIntMask3 CNT interrupt flag is set once for 4 every CNT counts at "0x0000" or peak (skiping 3 count).
+ ** \arg Timer4CntIntMask4 CNT interrupt flag is set once for 5 every CNT counts at "0x0000" or peak (skiping 4 count).
+ ** \arg Timer4CntIntMask5 CNT interrupt flag is set once for 6 every CNT counts at "0x0000" or peak (skiping 5 count).
+ ** \arg Timer4CntIntMask6 CNT interrupt flag is set once for 7 every CNT counts at "0x0000" or peak (skiping 6 count).
+ ** \arg Timer4CntIntMask7 CNT interrupt flag is set once for 8 every CNT counts at "0x0000" or peak (skiping 7 count).
+ ** \arg Timer4CntIntMask8 CNT interrupt flag is set once for 9 every CNT counts at "0x0000" or peak (skiping 8 count).
+ ** \arg Timer4CntIntMask9 CNT interrupt flag is set once for 10 every CNT counts at "0x0000" or peak (skiping 9 count).
+ ** \arg Timer4CntIntMask10 CNT interrupt flag is set once for 11 every CNT counts at "0x0000" or peak (skiping 10 count).
+ ** \arg Timer4CntIntMask11 CNT interrupt flag is set once for 12 every CNT counts at "0x0000" or peak (skiping 11 count).
+ ** \arg Timer4CntIntMask12 CNT interrupt flag is set once for 13 every CNT counts at "0x0000" or peak (skiping 12 count).
+ ** \arg Timer4CntIntMask13 CNT interrupt flag is set once for 14 every CNT counts at "0x0000" or peak (skiping 13 count).
+ ** \arg Timer4CntIntMask14 CNT interrupt flag is set once for 15 every CNT counts at "0x0000" or peak (skiping 14 count).
+ ** \arg Timer4CntIntMask15 CNT interrupt flag is set once for 16 every CNT counts at "0x0000" or peak (skiping 15 count).
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_CNT_SetIntMaskTimes(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_int_t enIntType,
+ en_timer4_cnt_int_mask_t enMaskTimes)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
+ DDL_ASSERT(IS_VALID_CNT_INT_MSK(enMaskTimes));
+
+ enRet = Ok;
+ switch (enIntType)
+ {
+ case Timer4CntZeroMatchInt:
+ TMR4x->CVPR_f.ZIM = (uint16_t)enMaskTimes;
+ break;
+ case Timer4CntPeakMatchInt:
+ TMR4x->CVPR_f.PIM = (uint16_t)enMaskTimes;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 CNT interrupt mask times
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enIntType Timer4 CNT interrupt type
+ ** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
+ ** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
+ **
+ ** \retval Timer4CntIntMask0 CNT interrupt flag is always set(not masked) for every CNT count at "0x0000" or peak.
+ ** \retval Timer4CntIntMask1 CNT interrupt flag is set once for 2 every CNT counts at "0x0000" or peak (skiping 1 count).
+ ** \retval Timer4CntIntMask2 CNT interrupt flag is set once for 3 every CNT counts at "0x0000" or peak (skiping 2 count).
+ ** \retval Timer4CntIntMask3 CNT interrupt flag is set once for 4 every CNT counts at "0x0000" or peak (skiping 3 count).
+ ** \retval Timer4CntIntMask4 CNT interrupt flag is set once for 5 every CNT counts at "0x0000" or peak (skiping 4 count).
+ ** \retval Timer4CntIntMask5 CNT interrupt flag is set once for 6 every CNT counts at "0x0000" or peak (skiping 5 count).
+ ** \retval Timer4CntIntMask6 CNT interrupt flag is set once for 7 every CNT counts at "0x0000" or peak (skiping 6 count).
+ ** \retval Timer4CntIntMask7 CNT interrupt flag is set once for 8 every CNT counts at "0x0000" or peak (skiping 7 count).
+ ** \retval Timer4CntIntMask8 CNT interrupt flag is set once for 9 every CNT counts at "0x0000" or peak (skiping 8 count).
+ ** \retval Timer4CntIntMask9 CNT interrupt flag is set once for 10 every CNT counts at "0x0000" or peak (skiping 9 count).
+ ** \retval Timer4CntIntMask10 CNT interrupt flag is set once for 11 every CNT counts at "0x0000" or peak (skiping 10 count).
+ ** \retval Timer4CntIntMask11 CNT interrupt flag is set once for 12 every CNT counts at "0x0000" or peak (skiping 11 count).
+ ** \retval Timer4CntIntMask12 CNT interrupt flag is set once for 13 every CNT counts at "0x0000" or peak (skiping 12 count).
+ ** \retval Timer4CntIntMask13 CNT interrupt flag is set once for 14 every CNT counts at "0x0000" or peak (skiping 13 count).
+ ** \retval Timer4CntIntMask14 CNT interrupt flag is set once for 15 every CNT counts at "0x0000" or peak (skiping 14 count).
+ ** \retval Timer4CntIntMask15 CNT interrupt flag is set once for 16 every CNT counts at "0x0000" or peak (skiping 15 count).
+ **
+ ******************************************************************************/
+en_timer4_cnt_int_mask_t TIMER4_CNT_GetIntMaskTimes(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_cnt_int_t enIntType)
+{
+ uint16_t u16MaskTimes = 0u;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+ DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
+
+ switch (enIntType)
+ {
+ case Timer4CntZeroMatchInt:
+ u16MaskTimes = TMR4x->CVPR_f.ZIM;
+ break;
+ case Timer4CntPeakMatchInt:
+ u16MaskTimes = TMR4x->CVPR_f.PIM;
+ break;
+ default:
+ break;
+ }
+
+ return (en_timer4_cnt_int_mask_t)u16MaskTimes;
+}
+
+//@} // Timer4CntGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timer4_emb.c b/lib/hc32f460/driver/src/hc32f460_timer4_emb.c new file mode 100644 index 00000000..46e7e26b --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timer4_emb.c @@ -0,0 +1,274 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timer4_emb.c
+ **
+ ** A detailed description is available at
+ ** @link Timer4EmbGroup Timer4EMB description @endlink
+ **
+ ** - 2018-11-02 CDT First version for Device Driver Library of Timer4EMB.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timer4_emb.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup Timer4EmbGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter validity check for Timer4 unit */
+#define IS_VALID_TIMER4(__TMRx__) \
+( (M4_TMR41 == (__TMRx__)) || \
+ (M4_TMR42 == (__TMRx__)) || \
+ (M4_TMR43 == (__TMRx__)))
+
+/*!< Parameter valid check for EMB HOLD mode. */
+#define IS_VALID_EMB_HOLD_MODE(x) \
+( (EmbHoldPwm == (x)) || \
+ (EmbChangePwm == (x)))
+
+/*!< Parameter valid check for EMB state. */
+#define IS_VALID_EMB_STATE(x) \
+( (EmbTrigPwmOutputHiz == (x)) || \
+ (EmbTrigPwmOutputNormal == (x)) || \
+ (EmbTrigPwmOutputLowLevel == (x)) || \
+ (EmbTrigPwmOutputHighLevel == (x)))
+
+/*!< Timer4x ECER register address. */
+#define TMR4_ECERx(__TMRx__) \
+( (M4_TMR41 == (__TMRx__)) ? &M4_TMR4_CR->ECER1 : \
+ ((M4_TMR42 == (__TMRx__)) ? &M4_TMR4_CR->ECER2 : &M4_TMR4_CR->ECER3))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Initialize Timer4 EMB
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] pstcInitCfg The pointer of EMB configure structure
+ ** \arg This parameter detail refer @ref stc_timer4_emb_init_t
+ **
+ ** \retval Ok Initialize successfully
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - pstcInitCfg == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMER4_EMB_Init(M4_TMR4_TypeDef *TMR4x,
+ const stc_timer4_emb_init_t *pstcInitCfg)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x && pstcInitCfg pointer */
+ if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EMB_STATE(pstcInitCfg->enEmbState));
+ DDL_ASSERT(IS_VALID_EMB_HOLD_MODE(pstcInitCfg->enPwmHold));
+
+ /* Set EMB HOLD mode */
+ TMR4x->ECSR_f.HOLD = (uint16_t)(pstcInitCfg->enPwmHold);
+
+ /* Set EMB state */
+ *(__IO uint32_t *)TMR4_ECERx(TMR4x) = (uint32_t)(pstcInitCfg->enEmbState);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-initialize Timer4 EMB
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval Ok De-Initialize successfully
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_EMB_DeInit(M4_TMR4_TypeDef *TMR4x)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Set reset value(0x0000) to register ESCR */
+ TMR4x->ECSR = 0u;
+
+ /* Set reset value(0x0000) to register ECER */
+ *(__IO uint32_t *)TMR4_ECERx(TMR4x) = (uint32_t)0ul;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 EMB HOLD mode
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enHoldMode EMB HOLD mode
+ ** \arg EmbChangePwm Don't hold PWM output when EMB signal occurs
+ ** \arg EmbHoldPwm Hold PWM output when EMB signal occurs
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_EMB_SetHoldMode(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_emb_hold_mode_t enHoldMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EMB_HOLD_MODE(enHoldMode));
+
+ /* Set EMB HOLD mode */
+ TMR4x->ECSR_f.HOLD = (uint16_t)enHoldMode;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 EMB HOLD mode
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval EmbChangePwm Don't hold PWM output when EMB signal occurs
+ ** \retval EmbHoldPwm Hold PWM output when EMB signal occurs
+ **
+ ******************************************************************************/
+en_timer4_emb_hold_mode_t TIMER4_EMB_GetHoldMode(M4_TMR4_TypeDef *TMR4x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ return (en_timer4_emb_hold_mode_t)(TMR4x->ECSR_f.HOLD);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 EMB state
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enEmbState EMB state
+ ** \arg EmbTrigPwmOutputNormal PWM output signal normally.
+ ** \arg EmbTrigPwmOutputHiz PWM output Hiz signal.
+ ** \arg EmbTrigPwmOutputLowLevel PWM output low level signal.
+ ** \arg EmbTrigPwmOutputHighLevel PWM output high level signal.
+ **
+ ** \retval Ok Set successfully
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_EMB_SetState(const M4_TMR4_TypeDef *TMR4x,
+ en_timer4_emb_state_t enEmbState)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EMB_STATE(enEmbState));
+
+ /* Set EMB state */
+ *(__IO uint32_t *)TMR4_ECERx(TMR4x) = (uint32_t)enEmbState;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 EMB state
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ **
+ ** \retval EmbTrigPwmOutputNormal PWM output signal normally.
+ ** \retval EmbTrigPwmOutputHiz PWM output Hiz signal.
+ ** \retval EmbTrigPwmOutputLowLevel PWM output low level signal.
+ ** \retval EmbTrigPwmOutputHighLevel PWM output high level signal.
+ **
+ ******************************************************************************/
+en_timer4_emb_state_t TIMER4_EMB_GetState(const M4_TMR4_TypeDef *TMR4x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ return *(__IO en_timer4_emb_state_t *)TMR4_ECERx(TMR4x);
+}
+
+//@} // Timer4EmbGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timer4_oco.c b/lib/hc32f460/driver/src/hc32f460_timer4_oco.c new file mode 100644 index 00000000..35e97f1a --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timer4_oco.c @@ -0,0 +1,1291 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timer4_oco.c
+ **
+ ** A detailed description is available at
+ ** @link Timer4OcoGroup Timer4OCO description @endlink
+ **
+ ** - 2018-11-02 CDT First version for Device Driver Library of Timer4OCO.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timer4_oco.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup Timer4OcoGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter validity check for Timer4 unit */
+#define IS_VALID_TIMER4(__TMRx__) \
+( (M4_TMR41 == (__TMRx__)) || \
+ (M4_TMR42 == (__TMRx__)) || \
+ (M4_TMR43 == (__TMRx__)))
+
+/*!< Parameter validity check for oco channel */
+#define IS_VALID_OCO_CH(x) \
+( (Timer4OcoOuh == (x)) || \
+ (Timer4OcoOul == (x)) || \
+ (Timer4OcoOvh == (x)) || \
+ (Timer4OcoOvl == (x)) || \
+ (Timer4OcoOwh == (x)) || \
+ (Timer4OcoOwl == (x)))
+
+/*!< Parameter validity check for oco low channel */
+#define IS_VALID_OCO_LOW_CH(x) \
+( (Timer4OcoOul == (x)) || \
+ (Timer4OcoOvl == (x)) || \
+ (Timer4OcoOwl == (x)))
+
+/*!< Parameter validity check for even high channel */
+#define IS_VALID_OCO_HIGH_CH(x) \
+( (Timer4OcoOuh == (x)) || \
+ (Timer4OcoOvh == (x)) || \
+ (Timer4OcoOwh == (x)))
+
+/*!< Parameter validity check for occr buffer mode */
+#define IS_VALID_OCCR_BUF_MODE(x) \
+( (OccrBufDisable == (x)) || \
+ (OccrBufTrsfByCntZero == (x)) || \
+ (OccrBufTrsfByCntPeak == (x)) || \
+ (OccrBufTrsfByCntZeroOrCntPeak == (x)) || \
+ (OccrBufTrsfByCntZeroZicZero == (x)) || \
+ (OccrBufTrsfByCntPeakPicZero == (x)) || \
+ (OccrBufTrsfByCntZeroZicZeroOrCntPeakPicZero == (x)))
+
+/*!< Parameter validity check for ocmr buffer mode */
+#define IS_VALID_OCMR_BUF_MODE(x) \
+( (OcmrBufDisable == (x)) || \
+ (OcmrBufTrsfByCntZero == (x)) || \
+ (OcmrBufTrsfByCntPeak == (x)) || \
+ (OcmrBufTrsfByCntZeroOrCntPeak == (x)) || \
+ (OcmrBufTrsfByCntZeroZicZero == (x)) || \
+ (OcmrBufTrsfByCntPeakPicZero == (x)) || \
+ (OcmrBufTrsfByCntZeroZicZeroOrCntPeakPicZero == (x)))
+
+/*!< Parameter validity check for output level type */
+#define IS_VALID_OP_PORT_LEVEL(x) \
+( (OcPortLevelLow == (x)) || \
+ (OcPortLevelHigh == (x)))
+
+/*!< Parameter validity check for oco OP state */
+#define IS_VALID_OP_STATE(x) \
+( (OcoOpOutputLow == (x)) || \
+ (OcoOpOutputHigh == (x)) || \
+ (OcoOpOutputHold == (x)) || \
+ (OcoOpOutputReverse == (x)))
+
+/*!< Parameter validity check for oco OCF state */
+#define IS_VALID_OCF_STATE(x) \
+( (OcoOcfSet == (x)) || \
+ (OcoOcfHold == (x)))
+
+/*!< Get the specified register address of the specified Timer4 unit */
+#define TMR4_OCCRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->OCCRUH + ((uint32_t)(__CH__))*4ul)
+#define TMR4_OCMRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->OCMRHUH + ((uint32_t)(__CH__))*4ul)
+#define TMR4_OCERx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->OCERU + (((uint32_t)(__CH__))/2ul)*4ul)
+#define TMR4_OCSRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->OCSRU + (((uint32_t)(__CH__))/2ul)*4ul)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Initialize OCO module
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] pstcInitCfg The pointer of OCO configure structure
+ ** \arg This parameter detail refer @ref stc_timer4_oco_init_t
+ **
+ ** \retval Ok Initialize successfully
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - pstcInitCfg == NULL
+ ** - enCh is invalid
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_Init(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ const stc_timer4_oco_init_t* pstcInitCfg)
+{
+ __IO stc_tmr4_ocsr_field_t* pstcOCSR = NULL;
+ __IO stc_tmr4_ocer_field_t* pstcOCER = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x && pstcInitCfg pointer */
+ if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enOcoIntCmd));
+ DDL_ASSERT(IS_VALID_OP_PORT_LEVEL(pstcInitCfg->enPortLevel));
+ DDL_ASSERT(IS_VALID_OCMR_BUF_MODE(pstcInitCfg->enOcmrBufMode));
+ DDL_ASSERT(IS_VALID_OCCR_BUF_MODE(pstcInitCfg->enOccrBufMode));
+
+ enRet = Ok;
+ /* Get pointer of current channel OCO register address */
+ pstcOCER = (__IO stc_tmr4_ocer_field_t*)TMR4_OCERx(TMR4x,enCh);
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x,enCh);
+
+ /* Set OCMR and OCCR buffer mode */
+ if (IS_VALID_OCO_HIGH_CH(enCh)) /* channel: Timer4OcoOuh, Timer4OcoOvh, Timer4OcoOwh */
+ {
+ pstcOCSR->OCEH = (uint16_t)0u;
+ pstcOCSR->OCFH = (uint16_t)0u;
+
+ /* OCMR buffer */
+ switch (pstcInitCfg->enOcmrBufMode)
+ {
+ case OcmrBufDisable:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)0u;
+ break;
+ case OcmrBufTrsfByCntZero:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeak:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)3u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMMH = (uint16_t)1u;
+ pstcOCER->MHBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMMH = (uint16_t)1u;
+ pstcOCER->MHBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMMH = (uint16_t)1u;
+ pstcOCER->MHBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ if (enRet == Ok)
+ {
+ /* OCCR buffer */
+ switch (pstcInitCfg->enOccrBufMode)
+ {
+ case OccrBufDisable:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)0u;
+ break;
+ case OccrBufTrsfByCntZero:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeak:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)3u;
+ break;
+ case OccrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMCH = (uint16_t)1u;
+ pstcOCER->CHBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMCH = (uint16_t)1u;
+ pstcOCER->CHBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMCH = (uint16_t)1u;
+ pstcOCER->CHBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ if (enRet == Ok)
+ {
+ /* Set initial OP level */
+ pstcOCSR->OCPH = (uint16_t)(pstcInitCfg->enPortLevel);
+ /* set interrupt enable */
+ pstcOCSR->OCIEH = (uint16_t)(pstcInitCfg->enOcoIntCmd);
+ }
+ }
+ else if (IS_VALID_OCO_LOW_CH(enCh)) /* channel: Timer4OcoOul, Timer4OcoOvl, Timer4OcoOwl */
+ {
+ pstcOCSR->OCEL = (uint16_t)0u;
+ pstcOCSR->OCFL = (uint16_t)0u;
+
+ /* OCMR buffer */
+ switch (pstcInitCfg->enOcmrBufMode)
+ {
+ case OcmrBufDisable:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)0u;
+ break;
+ case OcmrBufTrsfByCntZero:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeak:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)3u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMML = (uint16_t)1u;
+ pstcOCER->MLBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMML = (uint16_t)1u;
+ pstcOCER->MLBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMML = (uint16_t)1u;
+ pstcOCER->MLBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ if (enRet == Ok)
+ {
+ /* OCCR buffer */
+ switch (pstcInitCfg->enOccrBufMode)
+ {
+ case OccrBufDisable:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)0u;
+ break;
+ case OccrBufTrsfByCntZero:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeak:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)3u;
+ break;
+ case OccrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMCL = (uint16_t)1u;
+ pstcOCER->CLBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMCL = (uint16_t)1u;
+ pstcOCER->CLBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMCL = (uint16_t)1u;
+ pstcOCER->CLBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ if (enRet == Ok)
+ {
+ /* Set initial OP level */
+ pstcOCSR->OCPL = (uint16_t)(pstcInitCfg->enPortLevel);
+ /* set interrupt enable */
+ pstcOCSR->OCIEL = (uint16_t)(pstcInitCfg->enOcoIntCmd);
+ }
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initialize OCO module
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ **
+ ** \retval Ok De-Initialize successfully.
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - enCh is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_DeInit(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh)
+{
+ __IO uint16_t* pu16OCCR = NULL;
+ __IO uint32_t u32OCMR = 0ul;
+ __IO stc_tmr4_ocsr_field_t* pstcOCSR = NULL;
+ __IO stc_tmr4_ocer_field_t* pstcOCER = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ enRet = Ok;
+ u32OCMR = TMR4_OCMRx(TMR4x, enCh);
+ pu16OCCR = (__IO uint16_t*)TMR4_OCCRx(TMR4x, enCh);
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x, enCh);
+ pstcOCER = (__IO stc_tmr4_ocer_field_t*)TMR4_OCERx(TMR4x, enCh);
+
+ /* Set default value */
+ if (IS_VALID_OCO_HIGH_CH(enCh)) /* channel: Timer4OcoOuh, Timer4OcoOvh, Timer4OcoOwh */
+ {
+ pstcOCSR->OCEH = (uint16_t)0u;
+ pstcOCSR->OCFH = (uint16_t)0u;
+ pstcOCSR->OCIEH = (uint16_t)0u;
+ pstcOCSR->OCPH = (uint16_t)0u;
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)0u;
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)0u;
+ pstcOCER->MCECH = (uint16_t)0u;
+ *pu16OCCR = (uint16_t)0u;
+ *(__IO uint16_t*)u32OCMR = (uint16_t)0u;
+ }
+ else if (IS_VALID_OCO_LOW_CH(enCh)) /* channel: Timer4OcoOul, Timer4OcoOvl, Timer4OcoOwl */
+ {
+ pstcOCSR->OCEL = (uint16_t)0u;
+ pstcOCSR->OCFL = (uint16_t)0u;
+ pstcOCSR->OCIEL = (uint16_t)0u;
+ pstcOCSR->OCPL = (uint16_t)0u;
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)0u;
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)0u;
+ pstcOCER->MCECL = (uint16_t)0u;
+ *pu16OCCR = (uint16_t)0u;
+ *(__IO uint32_t*)u32OCMR = (uint32_t)0ul;
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set occr buffer mode
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] enOccrBufMode Occr buffer mode
+ ** \arg OccrBufDisable Disable the register buffer function
+ ** \arg OccrBufTrsfByCntZero Register buffer transfer when counter value is 0x0000
+ ** \arg OccrBufTrsfByCntPeak Register buffer transfer when counter value is CPSR
+ ** \arg OccrBufTrsfByCntZeroOrCntPeak Register buffer transfer when the value is both 0 and CPSR
+ ** \arg OccrBufTrsfByCntZeroZicZero Register buffer transfer when counter value is 0x0000 and zero value detection mask counter value is 0
+ ** \arg OccrBufTrsfByCntPeakPicZero Register buffer transfer when counter value is CPSR and peak value detection mask counter value is 0 **
+ ** \arg OccrBufTrsfByCntZeroZicZeroOrCntPeakPicZero Register buffer transfer when counter value is 0x0000 and zero value detection mask counter value is 0 or
+ ** counter value is CPSR and peak value detection mask counter value is 0
+ ** \retval Ok OCO occr buffer mode initialized
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - enCh is invalid
+ ** - enOccrBufMode is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_SetOccrBufMode(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ en_timer4_oco_occr_buf_t enOccrBufMode)
+{
+ __IO stc_tmr4_ocer_field_t *pstcOCER = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_VALID_OCCR_BUF_MODE(enOccrBufMode));
+
+ enRet = Ok;
+ /* Get pointer of current channel OCO register address */
+ pstcOCER = (__IO stc_tmr4_ocer_field_t*)TMR4_OCERx(TMR4x, enCh);
+
+ /* Set OCCR buffer mode */
+ if (IS_VALID_OCO_HIGH_CH(enCh)) /* channel: Timer4OcoOuh, Timer4OcoOvh, Timer4OcoOwh */
+ {
+ /* OCCR buffer */
+ switch (enOccrBufMode)
+ {
+ case OccrBufDisable:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)0u;
+ break;
+ case OccrBufTrsfByCntZero:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeak:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMCH = (uint16_t)0u;
+ pstcOCER->CHBUFEN = (uint16_t)3u;
+ break;
+ case OccrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMCH = (uint16_t)1u;
+ pstcOCER->CHBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMCH = (uint16_t)1u;
+ pstcOCER->CHBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMCH = (uint16_t)1u;
+ pstcOCER->CHBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ else if (IS_VALID_OCO_LOW_CH(enCh)) /* channel: Timer4OcoOul, Timer4OcoOvl, Timer4OcoOwl */
+ {
+ /* OCCR buffer */
+ switch (enOccrBufMode)
+ {
+ case OccrBufDisable:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)0u;
+ break;
+ case OccrBufTrsfByCntZero:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeak:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMCL = (uint16_t)0u;
+ pstcOCER->CLBUFEN = (uint16_t)3u;
+ break;
+ case OccrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMCL = (uint16_t)1u;
+ pstcOCER->CLBUFEN = (uint16_t)1u;
+ break;
+ case OccrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMCL = (uint16_t)1u;
+ pstcOCER->CLBUFEN = (uint16_t)2u;
+ break;
+ case OccrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMCL = (uint16_t)1u;
+ pstcOCER->CLBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set occr buffer mode
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] enOcmrBufMode Occr buffer mode
+ ** \arg OcmrBufDisable Disable the register buffer function
+ ** \arg OcmrBufTrsfByCntZero Register buffer transfer when counter value is 0x0000
+ ** \arg OcmrBufTrsfByCntPeak Register buffer transfer when counter value is CPSR
+ ** \arg OcmrBufTrsfByCntZeroOrCntPeak Register buffer transfer when the value is both 0 and CPSR
+ ** \arg OcmrBufTrsfByCntZeroZicZero Register buffer transfer when counter value is 0x0000 and zero value detection mask counter value is 0
+ ** \arg OcmrBufTrsfByCntPeakPicZero Register buffer transfer when counter value is CPSR and peak value detection mask counter value is 0 **
+ ** \arg OcmrBufTrsfByCntZeroZicZeroOrCntPeakPicZero Register buffer transfer when counter value is 0x0000 and zero value detection mask counter value is 0 or
+ ** counter value is CPSR and peak value detection mask counter value is 0
+ **
+ ** \retval Ok OCO ocmr buffer mode initialized
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - enCh is invalid
+ ** - enOcmrBufMode is invalid.
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_SetOcmrBufMode(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ en_timer4_oco_ocmr_buf_t enOcmrBufMode)
+{
+ __IO stc_tmr4_ocer_field_t *pstcOCER = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_VALID_OCMR_BUF_MODE(enOcmrBufMode));
+
+ enRet = Ok;
+ /* Get pointer of current channel OCO register address */
+ pstcOCER = (__IO stc_tmr4_ocer_field_t*)TMR4_OCERx(TMR4x, enCh);
+
+ /* Set OCMR buffer mode */
+ if (IS_VALID_OCO_HIGH_CH(enCh)) /* channel: Timer4OcoOuh, Timer4OcoOvh, Timer4OcoOwh */
+ {
+ /* OCMR buffer */
+ switch (enOcmrBufMode)
+ {
+ case OcmrBufDisable:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)0u;
+ break;
+ case OcmrBufTrsfByCntZero:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeak:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMMH = (uint16_t)0u;
+ pstcOCER->MHBUFEN = (uint16_t)3u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMMH = (uint16_t)1u;
+ pstcOCER->MHBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMMH = (uint16_t)1u;
+ pstcOCER->MHBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMMH = (uint16_t)1u;
+ pstcOCER->MHBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ else if (IS_VALID_OCO_LOW_CH(enCh)) /* channel: Timer4OcoOul, Timer4OcoOvl, Timer4OcoOwl */
+ {
+ /* OCMR buffer */
+ switch (enOcmrBufMode)
+ {
+ case OcmrBufDisable:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)0u;
+ break;
+ case OcmrBufTrsfByCntZero:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeak:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroOrCntPeak:
+ pstcOCER->LMML = (uint16_t)0u;
+ pstcOCER->MLBUFEN = (uint16_t)3u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZero:
+ pstcOCER->LMML = (uint16_t)1u;
+ pstcOCER->MLBUFEN = (uint16_t)1u;
+ break;
+ case OcmrBufTrsfByCntPeakPicZero:
+ pstcOCER->LMML = (uint16_t)1u;
+ pstcOCER->MLBUFEN = (uint16_t)2u;
+ break;
+ case OcmrBufTrsfByCntZeroZicZeroOrCntPeakPicZero:
+ pstcOCER->LMML = (uint16_t)1u;
+ pstcOCER->MLBUFEN = (uint16_t)3u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Extend the matching determination conditions of OCO channel
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] enCmd Extend the match conditions functional state
+ ** \arg Enable Extend the match conditions function
+ ** \arg Disable Don't extend the match conditions function
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_ExtMatchCondCmd(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ en_functional_state_t enCmd)
+{
+ __IO stc_tmr4_ocer_field_t *pstcOCER = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ /* Get pointer of current channel OCO register address */
+ pstcOCER = (__IO stc_tmr4_ocer_field_t*)TMR4_OCERx(TMR4x, enCh);
+ IS_VALID_OCO_HIGH_CH(enCh) ? (pstcOCER->MCECH = (uint16_t)enCmd) : (pstcOCER->MCECL = (uint16_t)enCmd);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set compare mode of OCO high channel
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] pstcMode pointer to structure of compare mode
+ ** \arg This parameter detail refer @ref stc_oco_high_ch_compare_mode_t
+ **
+ ** \retval Ok OCO high channel compare mode is set successfully.
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - pstcMode pointer is NULL
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_SetHighChCompareMode(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ const stc_oco_high_ch_compare_mode_t *pstcMode)
+{
+ uint16_t u16OCMR = 0u;
+ __IO uint16_t *pu16OCMR = NULL;
+ __IO stc_tmr4_ocer_field_t *pstcOCER = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x && pstcMode pointer */
+ if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcMode))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_HIGH_CH(enCh));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntZeroMatchOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntZeroNotMatchOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntUpCntMatchOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntPeakMatchOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntPeakNotMatchOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntDownCntMatchOpState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntZeroMatchOcfState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntUpCntMatchOcfState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntPeakMatchOcfState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntDownCntMatchOcfState));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcMode->enMatchConditionExtendCmd));
+
+ /* Get pointer of current channel OCO register address */
+ pu16OCMR = (__IO uint16_t*)TMR4_OCMRx(TMR4x, enCh);
+ pstcOCER = (__IO stc_tmr4_ocer_field_t*)TMR4_OCERx(TMR4x, enCh);
+
+ pstcOCER->MCECH = (uint16_t)(pstcMode->enMatchConditionExtendCmd);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntZeroMatchOpState << 10u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntZeroNotMatchOpState << 14u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntUpCntMatchOpState << 8u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntPeakMatchOpState << 6u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntPeakNotMatchOpState << 12u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntDownCntMatchOpState << 4u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntZeroMatchOcfState << 3u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntUpCntMatchOcfState << 2u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntPeakMatchOcfState << 1u);
+ u16OCMR |= (uint16_t)((uint16_t)pstcMode->enCntDownCntMatchOcfState << 0u);
+
+ *pu16OCMR = u16OCMR;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set compare mode of OCO low channel
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] pstcMode pointer to structure of compare mode
+ ** \arg This parameter detail refer @ref TIMER4_OCO_SetLowChCompareMode
+ **
+ ** \retval Ok OCO low channel compare mode is set successfully.
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - pstcMode pointer is NULL
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_SetLowChCompareMode(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ const stc_oco_low_ch_compare_mode_t *pstcMode)
+{
+ uint32_t u32OCMR = 0ul;
+ __IO uint32_t *pu32OCMR = NULL;
+ __IO stc_tmr4_ocer_field_t *pstcOCER = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer and pstcMode pointer */
+ if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcMode))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_LOW_CH(enCh));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntZeroLowMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntZeroLowMatchHighNotMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntZeroLowNotMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntZeroLowNotMatchHighNotMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntUpCntLowMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntUpCntLowMatchHighNotMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntUpCntLowNotMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntPeakLowMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntPeakLowMatchHighNotMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntPeakLowNotMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntPeakLowNotMatchHighNotMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntDownLowMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntDownLowMatchHighNotMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OP_STATE(pstcMode->enCntDownLowNotMatchHighMatchLowChOpState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntZeroMatchOcfState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntUpCntMatchOcfState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntPeakMatchOcfState));
+ DDL_ASSERT(IS_VALID_OCF_STATE(pstcMode->enCntDownCntMatchOcfState));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcMode->enMatchConditionExtendCmd));
+
+ /* Get pointer of current channel OCO register address */
+ pu32OCMR = (__IO uint32_t*)TMR4_OCMRx(TMR4x, enCh);
+ pstcOCER = (__IO stc_tmr4_ocer_field_t*)TMR4_OCERx(TMR4x, enCh);;
+
+ pstcOCER->MCECL = (uint16_t)(pstcMode->enMatchConditionExtendCmd);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntZeroLowMatchHighMatchLowChOpState << 26u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntZeroLowMatchHighNotMatchLowChOpState << 10u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntZeroLowNotMatchHighMatchLowChOpState << 30u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntZeroLowNotMatchHighNotMatchLowChOpState << 14u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntUpCntLowMatchHighMatchLowChOpState << 24u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntUpCntLowMatchHighNotMatchLowChOpState << 8u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntUpCntLowNotMatchHighMatchLowChOpState << 18u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntPeakLowMatchHighMatchLowChOpState << 22u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntPeakLowMatchHighNotMatchLowChOpState << 6u) ;
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntPeakLowNotMatchHighMatchLowChOpState << 28u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntPeakLowNotMatchHighNotMatchLowChOpState << 12u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntDownLowMatchHighMatchLowChOpState << 20u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntDownLowMatchHighNotMatchLowChOpState << 4u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntDownLowNotMatchHighMatchLowChOpState << 16u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntZeroMatchOcfState << 3u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntUpCntMatchOcfState << 2u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntPeakMatchOcfState << 1u);
+ u32OCMR |= (uint32_t)((uint32_t)pstcMode->enCntDownCntMatchOcfState << 0u);
+
+ *pu32OCMR = u32OCMR;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set output function
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] enCmd The output functional state
+ ** \arg Enable Enable output function
+ ** \arg Disable Disable output function
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_OutputCompareCmd(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ en_functional_state_t enCmd)
+{
+ __IO stc_tmr4_ocsr_field_t *pstcOCSR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ /* Get pointer of current channel OCO register address */
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x, enCh);
+
+ /* set register */
+ IS_VALID_OCO_HIGH_CH(enCh) ? (pstcOCSR->OCEH = (uint16_t)enCmd) : (pstcOCSR->OCEL = (uint16_t)enCmd);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set OCO interrupt function
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] enCmd The interrupt functional state
+ ** \arg Enable Enable interrupt function
+ ** \arg Disable Disable interrupt function
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_IrqCmd(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ en_functional_state_t enCmd)
+{
+ __IO stc_tmr4_ocsr_field_t *pstcOCSR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
+
+ /* Get pointer of current channel OCO register address */
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x, enCh);
+ /* set register */
+ IS_VALID_OCO_HIGH_CH(enCh) ? (pstcOCSR->OCIEH = (uint16_t)enCmd) : (pstcOCSR->OCIEL = (uint16_t)enCmd);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get OCO interrupt flag
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ **
+ ** \retval Reset None interrupt request on Timer4 OCO
+ ** \retval Set Detection interrupt request on Timer4 OCO
+ **
+ ******************************************************************************/
+en_flag_status_t TIMER4_OCO_GetIrqFlag(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh)
+{
+ en_flag_status_t enFlag = Reset;
+ __IO stc_tmr4_ocsr_field_t *pstcOCSR = NULL;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ /* Get pointer of current channel OCO register address */
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x, enCh);
+
+ /* set return value */
+ if (IS_VALID_OCO_HIGH_CH(enCh)) /* channel: Timer4OcoOuh, Timer4OcoOvh, Timer4OcoOwh */
+ {
+ enFlag = (en_flag_status_t)(pstcOCSR->OCFH);
+ }
+ else if (IS_VALID_OCO_LOW_CH(enCh)) /* channel: Timer4OcoOul, Timer4OcoOvl, Timer4OcoOwl */
+ {
+ enFlag = (en_flag_status_t)(pstcOCSR->OCFL);
+ }
+ else
+ {
+ /* Do nothing: only avoid MISRA warning */
+ }
+
+ return enFlag;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear OCO interrupt flag
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ **
+ ** \retval Ok OCO interrupt flag is clear
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_ClearIrqFlag(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh)
+{
+ __IO stc_tmr4_ocsr_field_t *pstcOCSR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+
+ /* Get pointer of current channel OCO register address */
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x, enCh);
+ /* set return value */
+ IS_VALID_OCO_HIGH_CH(enCh) ? (pstcOCSR->OCFH = 0u) : (pstcOCSR->OCFL = 0u);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set OP pin level of OCO
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] enLevel OP port level of OCO
+ ** \arg OcPortLevelLow Output low level to OC port
+ ** \arg OcPortLevelHigh Output high level to OC port
+ **
+ ** \retval Ok OCO interrupt flag is clear
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_SetOpPortLevel(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ en_timer4_oco_port_level_t enLevel)
+{
+ __IO stc_tmr4_ocsr_field_t *pstcOCSR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_VALID_OP_PORT_LEVEL(enLevel));
+
+ /* Get pointer of current channel OCO register address */
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x, enCh);
+ IS_VALID_OCO_HIGH_CH(enCh) ? (pstcOCSR->OCFH = (uint16_t)enLevel) : (pstcOCSR->OCFL = (uint16_t)enLevel);
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get OP pin level of OCO
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ **
+ ** \retval OcPortLevelLow Output low level to OC port
+ ** \retval OcPortLevelHigh Output high level to OC port
+ **
+ ******************************************************************************/
+en_timer4_oco_port_level_t TIMER4_OCO_GetOpPinLevel(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh)
+{
+ __IO stc_tmr4_ocsr_field_t *pstcOCSR = NULL;
+ en_timer4_oco_port_level_t enLevel = OcPortLevelLow;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ /* Get pointer of current channel OCO register address */
+ pstcOCSR = (__IO stc_tmr4_ocsr_field_t*)TMR4_OCSRx(TMR4x, enCh);
+
+ if (IS_VALID_OCO_HIGH_CH(enCh)) /* channel: Timer4OcoOuh, Timer4OcoOvh, Timer4OcoOwh */
+ {
+ enLevel = (en_timer4_oco_port_level_t)(pstcOCSR->OCPH);
+ }
+ else if (IS_VALID_OCO_LOW_CH(enCh)) /* channel: Timer4OcoOul, Timer4OcoOvl, Timer4OcoOwl */
+ {
+ enLevel = (en_timer4_oco_port_level_t)(pstcOCSR->OCPL);
+ }
+ else
+ {
+ /* Do nothing: only avoid MISRA warning */
+ }
+
+ return enLevel;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write OCCR register
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ ** \param [in] u16Occr The value of occr
+ ** \arg 16bit value
+ **
+ ** \retval Ok OCCR written
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_OCO_WriteOccr(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh,
+ uint16_t u16Occr)
+{
+ __IO uint16_t *pu16OCCR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+
+ /* Get pointer of current channel OCO register address */
+ pu16OCCR = (__IO uint16_t*)TMR4_OCCRx(TMR4x, enCh);
+ /* set register */
+ *pu16OCCR = u16Occr;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get OCCR register value
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of OCO
+ ** \arg Timer4OcoOuh Timer oco channel:OUH
+ ** \arg Timer4OcoOul Timer oco channel:OUL
+ ** \arg Timer4OcoOvh Timer oco channel:OVH
+ ** \arg Timer4OcoOvl Timer oco channel:OVL
+ ** \arg Timer4OcoOwh Timer oco channel:OWH
+ ** \arg Timer4OcoOwl Timer oco channel:OWL
+ **
+ ** \retval OCCR register value
+ **
+ ******************************************************************************/
+uint16_t TIMER4_OCO_ReadOccr(const M4_TMR4_TypeDef *TMR4x,
+ en_timer4_oco_ch_t enCh)
+{
+ __IO uint16_t* pu16OCCR = NULL;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+ DDL_ASSERT(IS_VALID_OCO_CH(enCh));
+
+ /* Get pointer of current channel OCO register address */
+ pu16OCCR = (__IO uint16_t*)TMR4_OCCRx(TMR4x, enCh);
+
+ return (*pu16OCCR);
+}
+
+//@} // Timer4OcoGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timer4_pwm.c b/lib/hc32f460/driver/src/hc32f460_timer4_pwm.c new file mode 100644 index 00000000..fb4090a8 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timer4_pwm.c @@ -0,0 +1,596 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timer4_pwm.c
+ **
+ ** A detailed description is available at
+ ** @link Timer4PwmGroup Timer4PWM description @endlink
+ **
+ ** - 2018-11-02 CDT First version for Device Driver Library of Timer4PWM.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timer4_pwm.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup Timer4PwmGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter validity check for Timer4 unit */
+#define IS_VALID_TIMER4(__TMRx__) \
+( (M4_TMR41 == (__TMRx__)) || \
+ (M4_TMR42 == (__TMRx__)) || \
+ (M4_TMR43 == (__TMRx__)))
+
+/*!< Parameter validity check for PWM channel */
+#define IS_VALID_PWM_CH(x) \
+( (Timer4PwmU == (x)) || \
+ (Timer4PwmV == (x)) || \
+ (Timer4PwmW == (x)))
+
+/*!< Parameter validity check for PWM mode */
+#define IS_VALID_PWM_MODE(x) \
+( (PwmThroughMode == (x)) || \
+ (PwmDeadTimerMode == (x)) || \
+ (PwmDeadTimerFilterMode == (x)))
+
+/*!< Parameter valid check for PWM output state. */
+#define IS_VALID_PWM_OUTPUT_STATE(x) \
+( (PwmHPwmLHold == (x)) || \
+ (PwmHPwmLReverse == (x)) || \
+ (PwmHReversePwmLHold == (x)) || \
+ (PwmHHoldPwmLReverse == (x)))
+
+/*!< Parameter valid check for PWM clock division. */
+#define IS_VALID_PWM_CLK_DIV(x) \
+( (PwmPlckDiv1 == (x)) || \
+ (PwmPlckDiv2 == (x)) || \
+ (PwmPlckDiv4 == (x)) || \
+ (PwmPlckDiv8 == (x)) || \
+ (PwmPlckDiv16 == (x)) || \
+ (PwmPlckDiv32 == (x)) || \
+ (PwmPlckDiv64 == (x)) || \
+ (PwmPlckDiv128 == (x)))
+
+/*!< Get the specified register address of the specified Timer4 unit */
+#define TMR4_RCSRx(__TMR4x__) ((uint32_t)&(__TMR4x__)->RCSR)
+#define TMR4_POCRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->POCRU + ((uint32_t)(__CH__))*4ul)
+#define TMR4_PDARx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->PDARU + ((uint32_t)(__CH__))*8ul)
+#define TMR4_PDBRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->PDBRU + ((uint32_t)(__CH__))*8ul)
+#define TMR4_PFSRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->PFSRU + ((uint32_t)(__CH__))*8ul)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Initialize a couple PWM channels
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ ** \param [in] pstcInitCfg The pointer of PWM configure structure
+ ** \arg This parameter detail refer @ref stc_timer4_pwm_init_t
+ **
+ ** \retval Ok Initialize successfully
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - pstcInitCfg == NULL
+ ** - enCh is invalid
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_Init(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh,
+ const stc_timer4_pwm_init_t *pstcInitCfg)
+{
+ __IO stc_tmr4_pocr_field_t *pstcPOCR_f = NULL;
+ __IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
+ en_result_t enRet = Ok;
+
+ /* Check TMR4x && pstcInitCfg pointer */
+ if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PWM_MODE(pstcInitCfg->enMode));
+ DDL_ASSERT(IS_VALID_PWM_CLK_DIV(pstcInitCfg->enClkDiv));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enRtIntMaskCmd));
+ DDL_ASSERT(IS_VALID_PWM_OUTPUT_STATE(pstcInitCfg->enOutputState));
+
+ /* Get pointer of current channel PWM register address */
+ pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
+ pstcPOCR_f = (__IO stc_tmr4_pocr_field_t*)TMR4_POCRx(TMR4x, enCh);
+
+ /* Configure PWM mode */
+ pstcPOCR_f->PWMMD = (uint16_t)(pstcInitCfg->enMode);
+
+ /* Configure PWM mode */
+ pstcPOCR_f->LVLS = (uint16_t)(pstcInitCfg->enOutputState);
+
+ /* Set timer clock division */
+ pstcPOCR_f->DIVCK = (uint16_t)(pstcInitCfg->enClkDiv);
+
+ /* Set interrupt mask */
+ switch (enCh)
+ {
+ case Timer4PwmU:
+ pstcRCSR_f->RTIDU = (uint16_t)(pstcInitCfg->enRtIntMaskCmd);
+ break;
+ case Timer4PwmV:
+ pstcRCSR_f->RTIDV = (uint16_t)(pstcInitCfg->enRtIntMaskCmd);
+ break;
+ case Timer4PwmW:
+ pstcRCSR_f->RTIDW = (uint16_t)(pstcInitCfg->enRtIntMaskCmd);
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initialize a couple PWM channels
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ **
+ ** \retval Ok De-Initialize successfully.
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - enCh out of range
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_DeInit(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh)
+{
+ en_result_t enRet = Ok;
+ __IO uint16_t *pu16PDAR = NULL;
+ __IO uint16_t *pu16PDBR = NULL;
+ __IO uint16_t *pu16PFSR = NULL;
+ __IO stc_tmr4_pocr_field_t *pstcPOCR_f = NULL;
+ __IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Get pointer of current channel PWM register address */
+ pu16PDAR = (__IO uint16_t*)TMR4_PDARx(TMR4x, enCh);
+ pu16PDBR = (__IO uint16_t*)TMR4_PDBRx(TMR4x, enCh);
+ pu16PFSR = (__IO uint16_t*)TMR4_PFSRx(TMR4x, enCh);
+ pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
+ pstcPOCR_f = (__IO stc_tmr4_pocr_field_t*)TMR4_POCRx(TMR4x, enCh);
+
+ *pu16PDAR = (uint16_t)0u;
+ *pu16PDBR = (uint16_t)0u;
+ *pu16PFSR = (uint16_t)0u;
+ pstcPOCR_f->DIVCK = (uint16_t)0u;
+ pstcPOCR_f->LVLS = (uint16_t)0u;
+ pstcPOCR_f->PWMMD = (uint16_t)0u;
+
+ switch (enCh)
+ {
+ case Timer4PwmU:
+ pstcRCSR_f->RTIDU = (uint16_t)0u;
+ break;
+ case Timer4PwmV:
+ pstcRCSR_f->RTIDV = (uint16_t)0u;
+ break;
+ case Timer4PwmW:
+ pstcRCSR_f->RTIDW = (uint16_t)0u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ else
+ {
+ enRet = ErrorInvalidParameter;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Start PWM timer
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ **
+ ** \retval Ok Start timer successfully
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - enCh out of range
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_StartTimer(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ enRet = Ok;
+ /* Get pointer of current channel PWM register address */
+ pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
+
+ switch (enCh)
+ {
+ case Timer4PwmU:
+ pstcRCSR_f->RTEU = (uint16_t)1u;
+ break;
+ case Timer4PwmV:
+ pstcRCSR_f->RTEV = (uint16_t)1u;
+ break;
+ case Timer4PwmW:
+ pstcRCSR_f->RTEW = (uint16_t)1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Stop PWM timer
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ **
+ ** \retval Ok Stop timer successfully
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - enCh out of range
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_StopTimer(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PWM_CH(enCh));
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ enRet = Ok;
+
+ /* Get pointer of current channel PWM register address */
+ pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
+ switch (enCh)
+ {
+ case Timer4PwmU:
+ pstcRCSR_f->RTSU = (uint16_t)1u;
+ break;
+ case Timer4PwmV:
+ pstcRCSR_f->RTSV = (uint16_t)1u;
+ break;
+ case Timer4PwmW:
+ pstcRCSR_f->RTSW = (uint16_t)1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get PWM reload-timer interrupt flag
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ **
+ ** \retval Reset None interrupt request on PWM reload-timer
+ ** \retval Set Detection interrupt request on PWM reload-timer
+ **
+ ******************************************************************************/
+en_flag_status_t TIMER4_PWM_GetIrqFlag(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh)
+{
+ uint16_t u16Flag = 0u;
+ __IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PWM_CH(enCh));
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+
+ /* Get pointer of current channel PWM register address */
+ pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
+
+ switch (enCh)
+ {
+ case Timer4PwmU:
+ u16Flag = pstcRCSR_f->RTIFU;
+ break;
+ case Timer4PwmV:
+ u16Flag = pstcRCSR_f->RTIFV;
+ break;
+ case Timer4PwmW:
+ u16Flag = pstcRCSR_f->RTIFW;
+ break;
+ default:
+ break;
+ }
+
+ return (en_flag_status_t)u16Flag;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear PWM reload-timer interrupt flag
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ **
+ ** \retval Ok PWM reload-timer interrupt flag is clear
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - enCh out of range
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_ClearIrqFlag(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PWM_CH(enCh));
+
+ enRet = Ok;
+ /* Get pointer of current channel PWM register address */
+ pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
+ switch (enCh)
+ {
+ case Timer4PwmU:
+ pstcRCSR_f->RTICU = (uint16_t)1u;
+ break;
+ case Timer4PwmV:
+ pstcRCSR_f->RTICV = (uint16_t)1u;
+ break;
+ case Timer4PwmW:
+ pstcRCSR_f->RTICW = (uint16_t)1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write timer count cycle
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ ** \param [in] u16PDAR PDAR value
+ ** \arg 0~65535
+ ** \param [in] u16PDBR PDBR value
+ ** \arg 0~65535
+ **
+ ** \retval Ok Timer count cycle is written
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_WriteDeadRegionValue(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh,
+ uint16_t u16PDAR,
+ uint16_t u16PDBR)
+{
+ __IO uint16_t *pu16PDAR = NULL;
+ __IO uint16_t *pu16PDBR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PWM_CH(enCh));
+
+ /* Get pointer of current channel PWM register address */
+ pu16PDAR = (__IO uint16_t *)TMR4_PDARx(TMR4x, enCh);
+ pu16PDBR = (__IO uint16_t *)TMR4_PDBRx(TMR4x, enCh);
+
+ /* set the register */
+ *pu16PDAR = u16PDAR;
+ *pu16PDBR = u16PDBR;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read dead region count value
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ ** \param [out] u16PDAR Pointer of uint16_t type
+ ** \arg 0~65535
+ ** \param [out] u16PDBR Pointer of uint16_t type
+ ** \arg 0~65535
+ **
+ ** \retval Ok Read successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_ReadDeadRegionValue(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh,
+ uint16_t *u16PDAR,
+ uint16_t *u16PDBR)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PWM_CH(enCh));
+
+ /* Get pointer of current channel PWM register address */
+ *u16PDAR = *(__IO uint16_t *)TMR4_PDARx(TMR4x, enCh);
+ *u16PDBR = *(__IO uint16_t *)TMR4_PDBRx(TMR4x, enCh);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set cycle of PWM timer
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Channel of PWM
+ ** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
+ ** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
+ ** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
+ ** \param [in] u16Count PWM pulse counter value
+ ** \arg 0~65535
+ **
+ ** \retval Ok Cycle of PWM timer is set
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_PWM_SetFilterCountValue(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_pwm_ch_t enCh,
+ uint16_t u16Count)
+{
+ __IO uint16_t *pu16PFSR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PWM_CH(enCh));
+
+ /* Get pointer of current channel PWM register address */
+ pu16PFSR = (__IO uint16_t*)TMR4_PFSRx(TMR4x, enCh);
+ *pu16PFSR =u16Count;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+//@} // Timer4PwmGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timer4_sevt.c b/lib/hc32f460/driver/src/hc32f460_timer4_sevt.c new file mode 100644 index 00000000..bd650374 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timer4_sevt.c @@ -0,0 +1,589 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timer4_sevt.c
+ **
+ ** A detailed description is available at
+ ** @link Timer4SevtGroup Timer4SEVT description @endlink
+ **
+ ** - 2018-11-02 CDT First version for Device Driver Library of Timer4SEVT.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timer4_sevt.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup Timer4SevtGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter validity check for Timer4 unit */
+#define IS_VALID_TIMER4(__TMRx__) \
+( (M4_TMR41 == (__TMRx__)) || \
+ (M4_TMR42 == (__TMRx__)) || \
+ (M4_TMR43 == (__TMRx__)))
+
+/*!< Parameter validity check for SEVT channel */
+#define IS_VALID_SEVT_CH(x) \
+( (Timer4SevtCh0 == (x)) || \
+ (Timer4SevtCh1 == (x)) || \
+ (Timer4SevtCh2 == (x)) || \
+ (Timer4SevtCh3 == (x)) || \
+ (Timer4SevtCh4 == (x)) || \
+ (Timer4SevtCh5 == (x)))
+
+/*!< Parameter validity check for adct buffer mode */
+#define IS_VALID_SEVT_BUF_MODE(x) \
+( (SevtBufDisable == (x)) || \
+ (SevtBufCntZero == (x)) || \
+ (SevtBufCntPeak == (x)) || \
+ (SevtBufCntZeroOrCntPeak == (x)) || \
+ (SevtBufCntZeroZicZero == (x)) || \
+ (SevtBufCntPeakPicZero == (x)) || \
+ (SevtBufCntZeroZicZeroOrCntPeakPicZero == (x)))
+
+/*!< Parameter validity check for SEVT trigger event */
+#define IS_VALID_SEVT_TRG_EVT(x) \
+( (SevtTrgEvtSCMUH == (x)) || \
+ (SevtTrgEvtSCMUL == (x)) || \
+ (SevtTrgEvtSCMVH == (x)) || \
+ (SevtTrgEvtSCMVL == (x)) || \
+ (SevtTrgEvtSCMWH == (x)) || \
+ (SevtTrgEvtSCMWL == (x)))
+
+/*!< Parameter validity check for SEVT OCCR selection */
+#define IS_VALID_SEVT_OCCR_SEL(x) \
+( (SevtSelOCCRxh == (x)) || \
+ (SevtSelOCCRxl == (x)))
+
+/*!< Parameter validity check for SEVT running mode */
+#define IS_VALID_SEVT_MODE(x) \
+( (SevtDelayTrigMode == (x)) || \
+ (SevtCompareTrigMode == (x)))
+
+/*!< Parameter validity check for SEVT mask time */
+#define IS_VALID_SEVT_MSK(x) \
+( (Timer4SevtMask0 == (x)) || \
+ (Timer4SevtMask1 == (x)) || \
+ (Timer4SevtMask2 == (x)) || \
+ (Timer4SevtMask3 == (x)) || \
+ (Timer4SevtMask4 == (x)) || \
+ (Timer4SevtMask5 == (x)) || \
+ (Timer4SevtMask6 == (x)) || \
+ (Timer4SevtMask7 == (x)) || \
+ (Timer4SevtMask8 == (x)) || \
+ (Timer4SevtMask9 == (x)) || \
+ (Timer4SevtMask10 == (x)) || \
+ (Timer4SevtMask11 == (x)) || \
+ (Timer4SevtMask12 == (x)) || \
+ (Timer4SevtMask13 == (x)) || \
+ (Timer4SevtMask14 == (x)) || \
+ (Timer4SevtMask15 == (x)))
+
+/*!< Get the specified register address of the specified Timer4 unit */
+#define TMR4_SCCRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->SCCRUH + ((uint32_t)(__CH__))*4ul)
+#define TMR4_SCSRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->SCSRUH + ((uint32_t)(__CH__))*4ul)
+#define TMR4_SCMRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->SCMRUH + ((uint32_t)(__CH__))*4ul)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/**
+ *******************************************************************************
+ ** \brief Initialize a Special-Event channel
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ ** \param [in] pstcInitCfg The pointer of SEVT configure structure
+ ** \arg This parameter detail refer @ref stc_timer4_sevt_init_t
+ **
+ ** \retval Ok Initialize successfully
+ ** \retval ErrorInvalidParameter If one of following conditions are met:
+ ** - TMR4x is invalid
+ ** - pstcInitCfg == NULL
+ ** - enCh is invalid
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t TIMER4_SEVT_Init(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh,
+ const stc_timer4_sevt_init_t *pstcInitCfg)
+{
+ __IO uint16_t *pu16SCCR = NULL;
+ __IO stc_tmr4_scsr_field_t stcSCSR_f;
+ __IO stc_tmr4_scmr_field_t stcSCMR_f;
+ __IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
+ __IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x && pstcInitCfg pointer */
+ if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+ DDL_ASSERT(IS_VALID_SEVT_MODE(pstcInitCfg->enMode));
+ DDL_ASSERT(IS_VALID_SEVT_BUF_MODE(pstcInitCfg->enBuf));
+ DDL_ASSERT(IS_VALID_SEVT_MSK(pstcInitCfg->enMaskTimes));
+ DDL_ASSERT(IS_VALID_SEVT_TRG_EVT(pstcInitCfg->enTrigEvt));
+ DDL_ASSERT(IS_VALID_SEVT_OCCR_SEL(pstcInitCfg->enOccrSel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpAmcZicCmd));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpAmcPicCmd));
+
+ enRet = Ok;
+ /* Get actual address of register list of current channel */
+ pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
+ pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
+ pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
+
+ /* Configure default parameter */
+ *pu16SCCR = (uint16_t)0u;
+ *(__IO uint16_t*)pstcSCSR_f = (uint16_t)0x0000u;
+ *(__IO uint16_t*)pstcSCMR_f = (uint16_t)0xFF00u;
+
+ switch (pstcInitCfg->enBuf)
+ {
+ case SevtBufDisable:
+ stcSCSR_f.BUFEN = (uint16_t)0u;
+ stcSCSR_f.LMC = (uint16_t)0u;
+ break;
+ case SevtBufCntZero:
+ stcSCSR_f.BUFEN = (uint16_t)1u;
+ stcSCSR_f.LMC = (uint16_t)0u;
+ break;
+ case SevtBufCntPeak:
+ stcSCSR_f.BUFEN = (uint16_t)2u;
+ stcSCSR_f.LMC = (uint16_t)0u;
+ break;
+ case SevtBufCntZeroOrCntPeak:
+ stcSCSR_f.BUFEN = (uint16_t)3u;
+ stcSCSR_f.LMC = (uint16_t)0u;
+ break;
+ case SevtBufCntZeroZicZero:
+ stcSCSR_f.BUFEN = (uint16_t)1u;
+ stcSCSR_f.LMC = (uint16_t)1u;
+ break;
+ case SevtBufCntPeakPicZero:
+ stcSCSR_f.BUFEN = (uint16_t)2u;
+ stcSCSR_f.LMC = (uint16_t)1u;
+ break;
+ case SevtBufCntZeroZicZeroOrCntPeakPicZero:
+ stcSCSR_f.BUFEN = (uint16_t)3u;
+ stcSCSR_f.LMC = (uint16_t)1u;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ if (Ok == enRet)
+ {
+ /* Configure start trigger output channel number */
+ stcSCSR_f.EVTOS = (uint16_t)(pstcInitCfg->enTrigEvt);
+
+ /* Select SEVT running mode */
+ stcSCSR_f.EVTMS = (uint16_t)(pstcInitCfg->enMode);
+
+ /* select OCO OCCR register: OCCR(x) */
+ stcSCSR_f.EVTDS = (uint16_t)(pstcInitCfg->enOccrSel);
+
+ /* Set the comparison with CNT interrupt mask counter */
+ stcSCMR_f.AMC = (uint16_t)(pstcInitCfg->enMaskTimes);
+ stcSCMR_f.MZCE = (uint16_t)(pstcInitCfg->enCmpAmcZicCmd);
+ stcSCMR_f.MPCE = (uint16_t)(pstcInitCfg->enCmpAmcPicCmd);
+
+ *pstcSCSR_f = stcSCSR_f;
+ *pstcSCMR_f = stcSCMR_f;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initialize a SEVT channel
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ **
+ ** \retval Ok De-Initialize successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_SEVT_DeInit(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh)
+{
+ __IO uint16_t *pu16SCCR = NULL;
+ __IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
+ __IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+
+ /* Get actual address of register list of current channel */
+ pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
+ pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
+ pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
+
+ /* Configure default parameter */
+ *pu16SCCR = 0u;
+ *(__IO uint16_t*)pstcSCSR_f = (uint16_t)0x0000u;
+ *(__IO uint16_t*)pstcSCMR_f = (uint16_t)0xFF00u;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 SEVT trigger event.
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ ** \param [in] enTrgEvt Timer4 Special-EVT Event
+ ** \arg SevtTrgEvtSCMUH Timer4 Special-EVT Event: TMR4_Ux_SCMUH
+ ** \arg SevtTrgEvtSCMUL Timer4 Special-EVT Event: TMR4_Ux_SCMUL
+ ** \arg SevtTrgEvtSCMVH Timer4 Special-EVT Event: TMR4_Ux_SCMVH
+ ** \arg SevtTrgEvtSCMVL Timer4 Special-EVT Event: TMR4_Ux_SCMVL
+ ** \arg SevtTrgEvtSCMWH Timer4 Special-EVT Event: TMR4_Ux_SCMWH
+ ** \arg SevtTrgEvtSCMWL Timer4 Special-EVT Event: TMR4_Ux_SCMWL
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_SEVT_SetTriggerEvent(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh,
+ en_timer4_sevt_trigger_evt_t enTrgEvt)
+{
+ __IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+ DDL_ASSERT(IS_VALID_SEVT_TRG_EVT(enTrgEvt));
+
+ /* Get actual address of register list of current channel */
+ pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
+ pstcSCSR_f->EVTOS = (uint16_t)(enTrgEvt);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 SEVT trigger condition.
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ ** \param [in] pstcTrigCond The pointer of SEVT trigger condition structure
+ ** \arg This parameter detail refer @ref stc_timer4_sevt_trigger_cond_t
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_SEVT_SetTriggerCond(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh,
+ const stc_timer4_sevt_trigger_cond_t *pstcTrigCond)
+{
+ __IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enUpMatchCmd));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enZeroMatchCmd));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enDownMatchCmd));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enPeakMatchCmd));
+
+ /* Get actual address of register list of current channel */
+ pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
+ pstcSCSR_f->PEN = (uint16_t)(pstcTrigCond->enPeakMatchCmd);
+ pstcSCSR_f->ZEN = (uint16_t)(pstcTrigCond->enZeroMatchCmd);
+ pstcSCSR_f->UEN = (uint16_t)(pstcTrigCond->enUpMatchCmd);
+ pstcSCSR_f->DEN = (uint16_t)(pstcTrigCond->enDownMatchCmd);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Write compare or delay value to Timer4 SEVT
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ ** \param [in] u16SccrVal Timer4 SEVT compare value
+ **
+ ** \retval Ok Compare or delay value to Timer4 SEVT is set
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_SEVT_WriteSCCR(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh,
+ uint16_t u16SccrVal)
+{
+ __IO uint16_t *pu16SCCR = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* check parameters */
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+
+ /* Get actual address of register list of current channel */
+ pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
+ *pu16SCCR = u16SccrVal;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read compare value or delay value of ATVR
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ **
+ ** \retval Value of register SCCR
+ **
+ ******************************************************************************/
+uint16_t TIMER4_SEVT_ReadSCCR(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh)
+{
+ __IO uint16_t *pu16SCCR = NULL;
+
+ /* check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+
+ /* Get actual address of register list of current channel */
+ pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
+
+ return *pu16SCCR;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timer4 SEVT trigger event.
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ ** \param [in] enMaskTimes Timer4 Special-EVT event mask times
+ ** \arg Timer4SevtMask0 Mask 0 time.
+ ** \arg Timer4SevtMask1 Mask 1 times.
+ ** \arg Timer4SevtMask2 Mask 2 times.
+ ** \arg Timer4SevtMask3 Mask 3 times.
+ ** \arg Timer4SevtMask4 Mask 4 times.
+ ** \arg Timer4SevtMask5 Mask 5 times.
+ ** \arg Timer4SevtMask6 Mask 6 times.
+ ** \arg Timer4SevtMask7 Mask 7 times.
+ ** \arg Timer4SevtMask8 Mask 8 times.
+ ** \arg Timer4SevtMask9 Mask 9 times.
+ ** \arg Timer4SevtMask10 Mask 10 times
+ ** \arg Timer4SevtMask11 Mask 11 times
+ ** \arg Timer4SevtMask12 Mask 12 times
+ ** \arg Timer4SevtMask13 Mask 13 times
+ ** \arg Timer4SevtMask14 Mask 14 times
+ ** \arg Timer4SevtMask15 Mask 15 times
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter TMR4x is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMER4_SEVT_SetMaskTimes(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh,
+ en_timer4_sevt_mask_t enMaskTimes)
+{
+ __IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check TMR4x pointer */
+ if (IS_VALID_TIMER4(TMR4x))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+ DDL_ASSERT(IS_VALID_SEVT_MSK(enMaskTimes));
+
+ /* Get actual address of register list of current channel */
+ pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
+ pstcSCMR_f->AMC = (uint16_t)(enMaskTimes);
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer4 SEVT mask count.
+ **
+ ** \param [in] TMR4x Pointer to Timer4 instance register base
+ ** \arg M4_TMR41 Timer4 unit 1 instance register base
+ ** \arg M4_TMR42 Timer4 unit 2 instance register base
+ ** \arg M4_TMR43 Timer4 unit 3 instance register base
+ ** \param [in] enCh Timer4 SEVT channel
+ ** \arg Timer4SevtCh0 Timer4 SEVT channel:0
+ ** \arg Timer4SevtCh1 Timer4 SEVT channel:1
+ ** \arg Timer4SevtCh2 Timer4 SEVT channel:2
+ ** \arg Timer4SevtCh3 Timer4 SEVT channel:3
+ ** \arg Timer4SevtCh4 Timer4 SEVT channel:4
+ ** \arg Timer4SevtCh5 Timer4 SEVT channel:5
+ **
+ ** \retval Timer4SevtMask0 Mask 0 time.
+ ** \retval Timer4SevtMask1 Mask 1 times.
+ ** \retval Timer4SevtMask2 Mask 2 times.
+ ** \retval Timer4SevtMask3 Mask 3 times.
+ ** \retval Timer4SevtMask4 Mask 4 times.
+ ** \retval Timer4SevtMask5 Mask 5 times.
+ ** \retval Timer4SevtMask6 Mask 6 times.
+ ** \retval Timer4SevtMask7 Mask 7 times.
+ ** \retval Timer4SevtMask8 Mask 8 times.
+ ** \retval Timer4SevtMask9 Mask 9 times.
+ ** \retval Timer4SevtMask10 Mask 10 times
+ ** \retval Timer4SevtMask11 Mask 11 times
+ ** \retval Timer4SevtMask12 Mask 12 times
+ ** \retval Timer4SevtMask13 Mask 13 times
+ ** \retval Timer4SevtMask14 Mask 14 times
+ ** \retval Timer4SevtMask15 Mask 15 times
+ **
+ ******************************************************************************/
+en_timer4_sevt_mask_t TIMER4_SEVT_GetMaskTimes(M4_TMR4_TypeDef *TMR4x,
+ en_timer4_sevt_ch_t enCh)
+{
+ __IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
+ DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
+
+ /* Get actual address of register list of current channel */
+ pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
+
+ return (en_timer4_sevt_mask_t)pstcSCMR_f->AMC;
+}
+
+//@} // Timer4SevtGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timer6.c b/lib/hc32f460/driver/src/hc32f460_timer6.c new file mode 100644 index 00000000..9474fcac --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timer6.c @@ -0,0 +1,1820 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timer6.c
+ **
+ ** A detailed description is available at
+ ** @link Timer6Group Timer6 description @endlink
+ **
+ ** - 2018-11-23 CDT First version for Device Driver Library of Timer6.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timer6.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup Timer6Group
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for normal timer6 unit */
+#define IS_VALID_NORMAL_TIMER6_UNIT(__TMR6x__) \
+( (M4_TMR61 == (__TMR6x__)) || \
+ (M4_TMR62 == (__TMR6x__)) || \
+ (M4_TMR63 == (__TMR6x__)))
+
+/*!< Parameter valid check for period register*/
+#define IS_VALID_PERIOD_TYPE(x) \
+( (Timer6PeriodA == (x)) || \
+ (Timer6PeriodB == (x)) || \
+ (Timer6PeriodC == (x)))
+/*!< Parameter valid check for General compare register*/
+#define IS_VALID_GEN_CMP_TYPE(x) \
+( (Timer6GenCompareA == (x)) || \
+ (Timer6GenCompareB == (x)) || \
+ (Timer6GenCompareC == (x)) || \
+ (Timer6GenCompareD == (x)) || \
+ (Timer6GenCompareE == (x)) || \
+ (Timer6GenCompareF == (x)))
+
+/*!< Parameter valid check for Special compare register*/
+#define IS_VALID_SPECIAL_CMP_TYPE(x) \
+( (Timer6SpclCompA == (x)) || \
+ (Timer6SpclCompB == (x)) || \
+ (Timer6SpclCompC == (x)) || \
+ (Timer6SpclCompD == (x)) || \
+ (Timer6SpclCompE == (x)) || \
+ (Timer6SpclCompF == (x)))
+/*!< Parameter valid check for Count clock division */
+#define IS_VALID_COUNT_CLK_DIV(x) \
+( (Timer6PclkDiv1 == (x)) || \
+ (Timer6PclkDiv2 == (x)) || \
+ (Timer6PclkDiv4 == (x)) || \
+ (Timer6PclkDiv8 == (x)) || \
+ (Timer6PclkDiv16 == (x)) || \
+ (Timer6PclkDiv64 == (x)) || \
+ (Timer6PclkDiv256 == (x)) || \
+ (Timer6PclkDiv1024 == (x)))
+
+/*!< Parameter valid check for count mode */
+#define IS_VALID_COUNT_MODE(x) \
+( (Timer6CntSawtoothMode == (x)) || \
+ (Timer6CntTriangularModeA == (x)) || \
+ (Timer6CntTriangularModeB == (x)))
+
+/*!< Parameter valid check for count direction */
+#define IS_VALID_COUNT_DIR(x) \
+( (Timer6CntDirDown == (x)) || \
+ (Timer6CntDirUp == (x)))
+
+/*!< Parameter valid check for timer6 output port */
+#define IS_VALID_TIMER6_OUTPUT_PORT(x) \
+( (Timer6PWMA == (x)) || \
+ (Timer6PWMB == (x)))
+
+/*!< Parameter valid check for timer6 port mode */
+#define IS_VALID_TIMER6_PORT_MODE(x) \
+( (Timer6ModeCompareOutput == (x)) || \
+ (Timer6ModeCaptureInput == (x)))
+
+/*!< Parameter valid check for timer6 input port */
+#define IS_VALID_TIMER6_INPUT_PORT(x) \
+( (Timer6PWMA == (x)) || \
+ (Timer6PWMB == (x)) || \
+ (Timer6TrigA == (x)) || \
+ (Timer6TrigB == (x)))
+
+/*!< Parameter valid check for start/stop count output status */
+#define IS_VALID_STA_STP_OUTPUT_STATUS(x) \
+( (Timer6PWMxPortOutLow == (x)) || \
+ (Timer6PWMxPortOutHigh == (x)))
+
+/*!< Parameter valid check for match output status */
+#define IS_VALID_MATCH_OUTPUT_STATUS(x) \
+( (Timer6PWMxCompareLow == (x)) || \
+ (Timer6PWMxCompareHigh == (x)) || \
+ (Timer6PWMxCompareKeep == (x)) || \
+ (Timer6PWMxCompareInv == (x)))
+
+/*!< Parameter valid check for match output status */
+#define IS_VALID_MATCH_OUTPUT_STATUS(x) \
+( (Timer6PWMxCompareLow == (x)) || \
+ (Timer6PWMxCompareHigh == (x)) || \
+ (Timer6PWMxCompareKeep == (x)) || \
+ (Timer6PWMxCompareInv == (x)))
+
+/*!< Parameter valid check for port filter clock */
+#define IS_VALID_PORT_FILTER_CLOCK(x) \
+( (Timer6FltClkPclk0Div1 == (x)) || \
+ (Timer6FltClkPclk0Div4 == (x)) || \
+ (Timer6FltClkPclk0Div16 == (x)) || \
+ (Timer6FltClkPclk0Div64 == (x)))
+
+/*!< Parameter valid check for interrupt request source */
+#define IS_VALID_VPERR_PCNT_NUM(x) \
+( (Timer6PeriodCnts0 == (x)) || \
+ (Timer6PeriodCnts1 == (x)) || \
+ (Timer6PeriodCnts2 == (x)) || \
+ (Timer6PeriodCnts3 == (x)) || \
+ (Timer6PeriodCnts4 == (x)) || \
+ (Timer6PeriodCnts5 == (x)) || \
+ (Timer6PeriodCnts6 == (x)) || \
+ (Timer6PeriodCnts7 == (x)))
+/*!< Parameter valid check for interrupt request source */
+#define IS_VALID_VPERR_PCNT_EN_SOURCE(x) \
+( (Timer6PeriodCnteDisable == (x)) || \
+ (Timer6PeriodCnteMin == (x)) || \
+ (Timer6PeriodCnteMax == (x)) || \
+ (Timer6PeriodCnteBoth == (x)))
+
+/*!< Parameter valid check for interrupt request source */
+#define IS_VALID_IRQ_SOURCE(x) \
+( (Timer6INTENA == (x)) || \
+ (Timer6INTENB == (x)) || \
+ (Timer6INTENC == (x)) || \
+ (Timer6INTEND == (x)) || \
+ (Timer6INTENE == (x)) || \
+ (Timer6INTENF == (x)) || \
+ (Timer6INTENOVF == (x)) || \
+ (Timer6INTENUDF == (x)) || \
+ (Timer6INTENDTE == (x)) || \
+ (Timer6INTENSAU == (x)) || \
+ (Timer6INTENSAD == (x)) || \
+ (Timer6INTENSBU == (x)) || \
+ (Timer6INTENSBD == (x)))
+
+/*!< Parameter valid check for status type */
+#define IS_VALID_STATUS_TYPE(x) \
+( (Timer6CMAF == (x)) || \
+ (Timer6CMBF == (x)) || \
+ (Timer6CMCF == (x)) || \
+ (Timer6CMDF == (x)) || \
+ (Timer6CMEF == (x)) || \
+ (Timer6CMFF == (x)) || \
+ (Timer6OVFF == (x)) || \
+ (Timer6UDFF == (x)) || \
+ (Timer6DTEF == (x)) || \
+ (Timer6CMSAUF == (x)) || \
+ (Timer6CMSADF == (x)) || \
+ (Timer6CMSBUF == (x)) || \
+ (Timer6CMSBDF == (x)) || \
+ (Timer6VPERNUM == (x)) || \
+ (Timer6DIRF == (x)))
+
+/*!< Parameter valid check for hardware up count/down count event type */
+#define IS_VALID_HW_COUNT_TYPE(x) \
+( (Timer6HwCntPWMALowPWMBRise == (x)) || \
+ (Timer6HwCntPWMALowPWMBFall == (x)) || \
+ (Timer6HwCntPWMAHighPWMBRise == (x)) || \
+ (Timer6HwCntPWMAHighPWMBFall == (x)) || \
+ (Timer6HwCntPWMBLowPWMARise == (x)) || \
+ (Timer6HwCntPWMBLowPWMAFall == (x)) || \
+ (Timer6HwCntPWMBHighPWMARise == (x)) || \
+ (Timer6HwCntPWMBHighPWMAFall == (x)) || \
+ (Timer6HwCntTRIGARise == (x)) || \
+ (Timer6HwCntTRIGAFall == (x)) || \
+ (Timer6HwCntTRIGBRise == (x)) || \
+ (Timer6HwCntTRIGBFall == (x)) || \
+ (Timer6HwCntAos0 == (x)) || \
+ (Timer6HwCntAos1 == (x)))
+
+/*!< Parameter valid check for hardware up start/stop/clear/capture event type */
+#define IS_VALID_HW_STA_STP_CLR_CAP_TYPE(x) \
+( (Timer6HwTrigAos0 == (x)) || \
+ (Timer6HwTrigAos1 == (x)) || \
+ (Timer6HwTrigPWMARise == (x)) || \
+ (Timer6HwTrigPWMAFall == (x)) || \
+ (Timer6HwTrigPWMBRise == (x)) || \
+ (Timer6HwTrigPWMBFall == (x)) || \
+ (Timer6HwTrigTimTriARise == (x)) || \
+ (Timer6HwTrigTimTriAFall == (x)) || \
+ (Timer6HwTrigTimTriBRise == (x)) || \
+ (Timer6HwTrigTimTriBFall == (x)) || \
+ (Timer6HwTrigEnd == (x)))
+
+/*!< Parameter valid check for timer6 input port type */
+#define IS_VALID_INPUT_PORT_TYPE(x) \
+( (Timer6xCHA == (x)) || \
+ (Timer6xCHB == (x)) || \
+ (Timer6TrigA == (x)) || \
+ (Timer6TrigB == (x)))
+
+/*!< Parameter valid check for GenCMP and period register buffer transfer type*/
+#define IS_VALID_GCMP_PRD_BUF_TYPE(x) \
+( (Timer6GcmpPrdSingleBuf == (x)) || \
+ (Timer6GcmpPrdDoubleBuf == (x)))
+
+/*!< Parameter valid check for special compare register buffer transfer type */
+#define IS_VALID_SPCL_BUF_TYPE(x) \
+( (Timer6SpclSingleBuf == (x)) || \
+ (Timer6SpclDoubleBuf == (x)))
+
+/*!< Parameter valid check for spcl register transfer opportunity type */
+#define IS_VALID_SPCL_TRANS_OPT_TYPE(x) \
+( (Timer6SplcOptNone == (x)) || \
+ (Timer6SplcOptOverFlow == (x)) || \
+ (Timer6SplcOptUnderFlow == (x)) || \
+ (Timer6SplcOptBoth == (x)))
+
+/*!< Parameter valid check for dead time register type */
+#define IS_VALID_DEAD_TIME_TYPE(x) \
+( (Timer6DeadTimUpAR == (x)) || \
+ (Timer6DeadTimUpBR == (x)) || \
+ (Timer6DeadTimDwnAR == (x)) || \
+ (Timer6DeadTimDwnBR == (x)))
+
+/*!< Parameter valid check for Z Phase input mask periods */
+#define IS_VALID_ZPHASE_MASK_PRD(x) \
+( (Timer6ZMaskDis == (x)) || \
+ (Timer6ZMask4Cyl == (x)) || \
+ (Timer6ZMask8Cyl == (x)) || \
+ (Tiemr6ZMask16Cyl == (x)))
+
+/*!< Parameter valid check for event source */
+#define IS_VALID_EVENT_SOURCE(x) ((x) <= 511)
+
+/*!< Parameter validity check for common trigger. */
+#define IS_VALID_TIMER6_COM_TRIGGER(x) \
+( (Timer6ComTrigger_1 == (x)) || \
+ (Timer6ComTrigger_2 == (x)) || \
+ (Timer6ComTrigger_1_2 == (x)))
+
+/*! TimerA registers reset value */
+#define TIMERA_REG_CNTER_RESET_VALUE (0x0000u)
+#define TIMERA_REG_GCONR_RESET_VALUE (0x00000100ul)
+#define TIMERA_REG_ICONR_RESET_VALUE (0x00000000ul)
+#define TIMERA_REG_PCONR_RESET_VALUE (0x00000000ul)
+#define TIMERA_REG_BCONR_RESET_VALUE (0x00000000ul)
+#define TIMERA_REG_DCONR_RESET_VALUE (0x00000000ul)
+#define TIMERA_REG_FCONR_RESET_VALUE (0x00000000ul)
+#define TIMERA_REG_VPERR_RESET_VALUE (0x00000000ul)
+
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * \brief Timer6 interrupt request enable or disable
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6Irq Irq type
+ * \param [in] bEn true/false
+ *
+ * \retval Ok: config successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ConfigIrq(M4_TMR6_TypeDef *TMR6x, en_timer6_irq_type_t enTimer6Irq, bool bEn)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_IRQ_SOURCE(enTimer6Irq));
+
+ switch (enTimer6Irq)
+ {
+ case Timer6INTENA:
+ TMR6x->ICONR_f.INTENA = bEn;
+ break;
+ case Timer6INTENB:
+ TMR6x->ICONR_f.INTENB = bEn;
+ break;
+ case Timer6INTENC:
+ TMR6x->ICONR_f.INTENC = bEn;
+ break;
+ case Timer6INTEND:
+ TMR6x->ICONR_f.INTEND = bEn;
+ break;
+ case Timer6INTENE:
+ TMR6x->ICONR_f.INTENE = bEn;
+ break;
+ case Timer6INTENF:
+ TMR6x->ICONR_f.INTENF = bEn;
+ break;
+ case Timer6INTENOVF:
+ TMR6x->ICONR_f.INTENOVF = bEn;
+ break;
+ case Timer6INTENUDF:
+ TMR6x->ICONR_f.INTENUDF = bEn;
+ break;
+ case Timer6INTENDTE:
+ TMR6x->ICONR_f.INTENDTE = bEn;
+ break;
+ case Timer6INTENSAU:
+ TMR6x->ICONR_f.INTENSAU = bEn;
+ break;
+ case Timer6INTENSAD:
+ TMR6x->ICONR_f.INTENSAD = bEn;
+ break;
+ case Timer6INTENSBU:
+ TMR6x->ICONR_f.INTENSBU = bEn;
+ break;
+ case Timer6INTENSBD:
+ TMR6x->ICONR_f.INTENSBD = bEn;
+ break;
+ default:
+ break;
+ }
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timer6 status flag
+ **
+ ** \param [in] TMR6x Timer6 unit
+ **
+ ** \param [in] enStatus Timer6 status type
+ **
+ ** \retval Timer6 status
+ **
+ ******************************************************************************/
+uint8_t Timer6_GetStatus(M4_TMR6_TypeDef *TMR6x, en_timer6_status_t enStatus)
+{
+ uint8_t status = 0u;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_STATUS_TYPE(enStatus));
+
+ switch (enStatus)
+ {
+ case Timer6CMAF:
+ status = (uint8_t)TMR6x->STFLR_f.CMAF;
+ break;
+ case Timer6CMBF:
+ status = (uint8_t)TMR6x->STFLR_f.CMBF;
+ break;
+ case Timer6CMCF:
+ status = (uint8_t)TMR6x->STFLR_f.CMCF;
+ break;
+ case Timer6CMDF:
+ status = (uint8_t)TMR6x->STFLR_f.CMDF;
+ break;
+ case Timer6CMEF:
+ status = (uint8_t)TMR6x->STFLR_f.CMEF;
+ break;
+ case Timer6CMFF:
+ status = (uint8_t)TMR6x->STFLR_f.CMFF;
+ break;
+ case Timer6OVFF:
+ status = (uint8_t)TMR6x->STFLR_f.OVFF;
+ break;
+ case Timer6UDFF:
+ status = (uint8_t)TMR6x->STFLR_f.UDFF;
+ break;
+ case Timer6DTEF:
+ status = (uint8_t)TMR6x->STFLR_f.DTEF;
+ break;
+ case Timer6CMSAUF:
+ status = (uint8_t)TMR6x->STFLR_f.CMSAUF;
+ break;
+ case Timer6CMSADF:
+ status = (uint8_t)TMR6x->STFLR_f.CMSADF;
+ break;
+ case Timer6CMSBUF:
+ status = (uint8_t)TMR6x->STFLR_f.CMSBUF;
+ break;
+ case Timer6CMSBDF:
+ status = (uint8_t)TMR6x->STFLR_f.CMSBDF;
+ break;
+ case Timer6VPERNUM:
+ status = (uint8_t)TMR6x->STFLR_f.VPERNUM;
+ break;
+ case Timer6DIRF:
+ status = (uint8_t)TMR6x->STFLR_f.DIRF;
+ break;
+ default:
+ break;
+ }
+
+ return status;
+}
+
+
+
+/**
+ *******************************************************************************
+ ** \brief De-Initialize Timer6 unit
+ **
+ ** \param [in] TMR6x Timer6 unit
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t Timer6_DeInit(M4_TMR6_TypeDef *TMR6x)
+{
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->CNTER = TIMERA_REG_CNTER_RESET_VALUE;
+ TMR6x->GCONR = TIMERA_REG_GCONR_RESET_VALUE;
+ TMR6x->PCONR = TIMERA_REG_PCONR_RESET_VALUE;
+ TMR6x->ICONR = TIMERA_REG_ICONR_RESET_VALUE;
+ TMR6x->BCONR = TIMERA_REG_BCONR_RESET_VALUE;
+ TMR6x->DCONR = TIMERA_REG_DCONR_RESET_VALUE;
+ TMR6x->FCONR = TIMERA_REG_FCONR_RESET_VALUE;
+ TMR6x->VPERR = TIMERA_REG_VPERR_RESET_VALUE;
+ TMR6x->HSTAR = 0x00000000ul;
+ TMR6x->HSTPR = 0x00000000ul;
+ TMR6x->HCLRR = 0x00000000ul;
+ TMR6x->HCPAR = 0x00000000ul;
+ TMR6x->HCPBR = 0x00000000ul;
+ TMR6x->HCUPR = 0x00000000ul;
+ TMR6x->HCDOR = 0x00000000ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Timer6 Base Config
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] pstcTimer6BaseCntCfg Bsee Config Pointer
+ *
+ * \retval Ok: Config Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_Init(M4_TMR6_TypeDef *TMR6x, const stc_timer6_basecnt_cfg_t* pstcTimer6BaseCntCfg)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcTimer6BaseCntCfg)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_COUNT_MODE(pstcTimer6BaseCntCfg->enCntMode));
+ DDL_ASSERT(IS_VALID_COUNT_DIR(pstcTimer6BaseCntCfg->enCntDir));
+ DDL_ASSERT(IS_VALID_COUNT_CLK_DIV(pstcTimer6BaseCntCfg->enCntClkDiv));
+
+
+ TMR6x->GCONR_f.MODE = pstcTimer6BaseCntCfg->enCntMode;
+ TMR6x->GCONR_f.DIR = pstcTimer6BaseCntCfg->enCntDir;
+ TMR6x->GCONR_f.CKDIV = pstcTimer6BaseCntCfg->enCntClkDiv;
+ }
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Timer6 Unit Start Count
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Config Successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_StartCount(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->GCONR_f.START = 1ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief TImer6 Unit Stop Count
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Config Successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_StopCount(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->GCONR_f.START = 0ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Timer6 Unit Set Count Value
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] u16Value Count Value
+ *
+ * \retval Ok: Config Successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetCount(M4_TMR6_TypeDef *TMR6x, uint16_t u16Value)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->CNTER_f.CNT = u16Value;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Timer6 Unit Get Count Value
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] u16Value Count Value
+ *
+ * \retval Ok: Config Successfully
+ *
+ ******************************************************************************/
+uint16_t Timer6_GetCount(M4_TMR6_TypeDef *TMR6x)
+{
+ uint16_t u16Value;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ u16Value = (uint16_t)TMR6x->CNTER_f.CNT;
+
+ return u16Value;
+}
+
+/*******************************************************************************
+ * \brief Timer6 Unit Clear Count Value
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ *
+ * \retval Ok: Set Successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ClearCount(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->CNTER_f.CNT = 0ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Timer6 unit set count period and buffer value
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6Periodx Period register name
+ * \param [in] u16Period Count period value
+ *
+ * \retval Ok: Set Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetPeriod(M4_TMR6_TypeDef *TMR6x, en_timer6_period_t enTimer6Periodx, uint16_t u16Period)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_PERIOD_TYPE(enTimer6Periodx));
+
+ switch (enTimer6Periodx)
+ {
+ case Timer6PeriodA:
+ TMR6x->PERAR = u16Period;
+ break;
+ case Timer6PeriodB:
+ TMR6x->PERBR = u16Period;
+ break;
+ case Timer6PeriodC:
+ TMR6x->PERCR = u16Period;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Timer6 unit Set General Compare Register Value(for PWM output)
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6Compare General Compare Register name
+ * \param [in] u16Compare General Compare Register value
+ *
+ * \retval Ok: Set Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetGeneralCmpValue(M4_TMR6_TypeDef *TMR6x, en_timer6_compare_t enTimer6Compare, uint16_t u16Compare)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_GEN_CMP_TYPE(enTimer6Compare));
+
+ switch (enTimer6Compare)
+ {
+ case Timer6GenCompareA:
+ TMR6x->GCMAR = u16Compare;
+ break;
+ case Timer6GenCompareB:
+ TMR6x->GCMBR = u16Compare;
+ break;
+ case Timer6GenCompareC:
+ TMR6x->GCMCR = u16Compare;
+ break;
+ case Timer6GenCompareD:
+ TMR6x->GCMDR = u16Compare;
+ break;
+ case Timer6GenCompareE:
+ TMR6x->GCMER = u16Compare;
+ break;
+ case Timer6GenCompareF:
+ TMR6x->GCMFR = u16Compare;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Timer6 unit Set Special Compare Register Value
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6SpclCmp General Compare Register name
+ * \param [in] u16SpclCmp General Compare Register value
+ *
+ * \retval Ok: Set Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetSpecialCmpValue(M4_TMR6_TypeDef *TMR6x, en_timer6_special_compare_t enTimer6SpclCmp, uint16_t u16SpclCmp)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_SPECIAL_CMP_TYPE(enTimer6SpclCmp));
+
+ switch (enTimer6SpclCmp)
+ {
+ case Timer6SpclCompA:
+ TMR6x->SCMAR = u16SpclCmp;
+ break;
+ case Timer6SpclCompB:
+ TMR6x->SCMBR = u16SpclCmp;
+ break;
+ case Timer6SpclCompC:
+ TMR6x->SCMCR = u16SpclCmp;
+ break;
+ case Timer6SpclCompD:
+ TMR6x->SCMDR = u16SpclCmp;
+ break;
+ case Timer6SpclCompE:
+ TMR6x->SCMER = u16SpclCmp;
+ break;
+ case Timer6SpclCompF:
+ TMR6x->SCMFR = u16SpclCmp;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Timer6 config general compare buffer transfer function
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6PWMPort PWM channel of timer6
+ * \param [in] pstcTimer6GenBufCfg General Compare Register Buffer Transfer Type Pointer
+ *
+ * \retval Ok: Set Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetGeneralBuf(M4_TMR6_TypeDef *TMR6x, en_timer6_chx_port_t enTimer6PWMPort, const stc_timer6_gcmp_buf_cfg_t* pstcTimer6GenBufCfg)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_TIMER6_OUTPUT_PORT(enTimer6PWMPort));
+ DDL_ASSERT(IS_VALID_GCMP_PRD_BUF_TYPE(pstcTimer6GenBufCfg->enGcmpBufTransType));
+
+ switch (enTimer6PWMPort)
+ {
+ case Timer6PWMA:
+ TMR6x->BCONR_f.BENA = pstcTimer6GenBufCfg->bEnGcmpTransBuf;
+ TMR6x->BCONR_f.BSEA = pstcTimer6GenBufCfg->enGcmpBufTransType;
+ break;
+ case Timer6PWMB:
+ TMR6x->BCONR_f.BENB = pstcTimer6GenBufCfg->bEnGcmpTransBuf;
+ TMR6x->BCONR_f.BSEB = pstcTimer6GenBufCfg->enGcmpBufTransType;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Timer6 config special compare buffer transfer function
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6SpclCmp Special Compare Register nameunit
+ * \param [in] pstcTimer6SpclBufCfg Special Compare Register Buffer Transfer Type Pointer
+ *
+ * \retval Ok: Set Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetSpecialBuf(M4_TMR6_TypeDef *TMR6x,en_timer6_special_compare_t enTimer6SpclCmp, const stc_timer6_spcl_buf_cfg_t* pstcTimer6SpclBufCfg)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_SPECIAL_CMP_TYPE(enTimer6SpclCmp));
+ DDL_ASSERT(IS_VALID_SPCL_BUF_TYPE(pstcTimer6SpclBufCfg->enSpclBufTransType));
+ DDL_ASSERT(IS_VALID_SPCL_TRANS_OPT_TYPE(pstcTimer6SpclBufCfg->enSpclBufOptType));
+
+ switch (enTimer6SpclCmp)
+ {
+ case Timer6SpclCompA:
+ TMR6x->BCONR_f.BENSPA = pstcTimer6SpclBufCfg->bEnSpclTransBuf;
+ TMR6x->BCONR_f.BSESPA = pstcTimer6SpclBufCfg->enSpclBufTransType;
+ TMR6x->BCONR_f.BTRSPA = pstcTimer6SpclBufCfg->enSpclBufOptType;
+ break;
+ case Timer6SpclCompB:
+ TMR6x->BCONR_f.BENSPB = pstcTimer6SpclBufCfg->bEnSpclTransBuf;
+ TMR6x->BCONR_f.BSESPB = pstcTimer6SpclBufCfg->enSpclBufTransType;
+ TMR6x->BCONR_f.BTRSPB = pstcTimer6SpclBufCfg->enSpclBufOptType;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Timer6 config period buffer transfer function
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] pstcTimer6PrdBufCfg Period Register Buffer Transfer Type Pointer
+ *
+ * \retval Ok: Set Successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetPeriodBuf(M4_TMR6_TypeDef *TMR6x, const stc_timer6_period_buf_cfg_t* pstcTimer6PrdBufCfg)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_GCMP_PRD_BUF_TYPE(pstcTimer6PrdBufCfg->enPeriodBufTransType));
+
+ TMR6x->BCONR_f.BENP = pstcTimer6PrdBufCfg->bEnPeriodTransBuf;
+ TMR6x->BCONR_f.BSEP = pstcTimer6PrdBufCfg->enPeriodBufTransType;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Timer6 unit get General Compare Register Value(for PWM output)
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6Compare General Compare Register name
+ *
+ *
+ * \retval u16TempValue: General Compare Register value
+ *
+ ******************************************************************************/
+uint16_t Timer6_GetGeneralCmpValue(M4_TMR6_TypeDef *TMR6x, en_timer6_compare_t enTimer6Compare)
+{
+ uint16_t u16TempValue = 0u;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_GEN_CMP_TYPE(enTimer6Compare));
+
+ switch (enTimer6Compare)
+ {
+ case Timer6GenCompareA:
+ u16TempValue = (uint16_t)TMR6x->GCMAR;
+ break;
+ case Timer6GenCompareB:
+ u16TempValue = (uint16_t)TMR6x->GCMBR;
+ break;
+ case Timer6GenCompareC:
+ u16TempValue = (uint16_t)TMR6x->GCMCR;
+ break;
+ case Timer6GenCompareD:
+ u16TempValue = (uint16_t)TMR6x->GCMDR;
+ break;
+ case Timer6GenCompareE:
+ u16TempValue = (uint16_t)TMR6x->GCMER;
+ break;
+ case Timer6GenCompareF:
+ u16TempValue = (uint16_t)TMR6x->GCMFR;
+ break;
+ default:
+ break;
+ }
+
+ return u16TempValue;
+}
+
+/***********************************************************************
+ * \brief Timer6 Config valid count period
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] pstcTimer6ValidPerCfg Valid Count Period Pointer
+ *
+ * \retval Ok: Config successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ***********************************************************************/
+en_result_t Timer6_SetValidPeriod(M4_TMR6_TypeDef *TMR6x, const stc_timer6_validper_cfg_t* pstcTimer6ValidPerCfg)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcTimer6ValidPerCfg)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_VPERR_PCNT_EN_SOURCE(pstcTimer6ValidPerCfg->enValidCdtEn));
+ DDL_ASSERT(IS_VALID_VPERR_PCNT_NUM(pstcTimer6ValidPerCfg->enValidCntNum));
+
+ TMR6x->VPERR_f.PCNTS = pstcTimer6ValidPerCfg->enValidCntNum;
+ TMR6x->VPERR_f.PCNTE = pstcTimer6ValidPerCfg->enValidCdtEn;
+ TMR6x->VPERR_f.SPPERIA = pstcTimer6ValidPerCfg->bPeriodSCMA;
+ TMR6x->VPERR_f.SPPERIB = pstcTimer6ValidPerCfg->bPeriodSCMB;
+ }
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Port input config(Trig)
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6InputPort Input port select @ref en_timer6_input_port_t
+ * \param [in] pstcTimer6PortInputCfg port Input Config Pointer
+ *
+ * \retval Ok: Set successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_PortInputConfig(M4_TMR6_TypeDef *TMR6x, en_timer6_input_port_t enTimer6InputPort, const stc_timer6_port_input_cfg_t* pstcTimer6PortInputCfg)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ if (NULL == pstcTimer6PortInputCfg)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ switch (enTimer6InputPort)
+ {
+ case Timer6xCHA:
+ TMR6x->FCONR_f.NOFIENGA = pstcTimer6PortInputCfg->bFltEn;
+ TMR6x->FCONR_f.NOFICKGA = pstcTimer6PortInputCfg->enFltClk;
+ break;
+
+ case Timer6xCHB:
+ TMR6x->FCONR_f.NOFIENGB = pstcTimer6PortInputCfg->bFltEn;
+ TMR6x->FCONR_f.NOFICKGB = pstcTimer6PortInputCfg->enFltClk;
+ break;
+
+ case Timer6TrigA:
+ M4_TMR61->FCONR_f.NOFIENTA = pstcTimer6PortInputCfg->bFltEn;
+ M4_TMR61->FCONR_f.NOFICKTA = pstcTimer6PortInputCfg->enFltClk;
+ break;
+
+ case Timer6TrigB:
+ M4_TMR61->FCONR_f.NOFIENTB = pstcTimer6PortInputCfg->bFltEn;
+ M4_TMR61->FCONR_f.NOFICKTB = pstcTimer6PortInputCfg->enFltClk;
+ break;
+
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ return enRet;
+}
+
+
+/*******************************************************************************
+ * \brief Set channel function
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6PWMPort Port to be configured @ref en_timer6_chx_port_t
+ * \param [in] enMode Channel mode @ref en_timer6_func_mode_t
+ * \retval None
+ ******************************************************************************/
+void Timer6_SetFunc(M4_TMR6_TypeDef *TMR6x, en_timer6_chx_port_t enTimer6PWMPort, en_timer6_func_mode_t enMode)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_TIMER6_OUTPUT_PORT(enTimer6PWMPort));
+ DDL_ASSERT(IS_VALID_TIMER6_PORT_MODE(enMode));
+
+ switch (enTimer6PWMPort)
+ {
+ case Timer6xCHA:
+ TMR6x->PCONR_f.CAPMDA = enMode;
+ break;
+
+ case Timer6xCHB:
+ TMR6x->PCONR_f.CAPMDB = enMode;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*******************************************************************************
+ * \brief Timer6 Output Port config
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6PWMPort Timer6 Port(PWMA/PWMB)
+ * \param [in] pstcTimer6PortOutCfg timer6 Port Config Pointer
+ *
+ * \retval Ok: Set successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_PortOutputConfig(M4_TMR6_TypeDef *TMR6x,
+ en_timer6_chx_port_t enTimer6PWMPort,
+ const stc_timer6_port_output_cfg_t* pstcTimer6PortOutCfg)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_TIMER6_OUTPUT_PORT(enTimer6PWMPort));
+
+ if (NULL == pstcTimer6PortOutCfg)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ switch (enTimer6PWMPort)
+ {
+ case Timer6PWMA:
+ TMR6x->PCONR_f.STACA = pstcTimer6PortOutCfg->enStaOut;
+ TMR6x->PCONR_f.STPCA = pstcTimer6PortOutCfg->enStpOut;
+ TMR6x->PCONR_f.STASTPSA = pstcTimer6PortOutCfg->enStaStp;
+ TMR6x->PCONR_f.CMPCA = pstcTimer6PortOutCfg->enCmpc;
+ TMR6x->PCONR_f.PERCA = pstcTimer6PortOutCfg->enPerc;
+ TMR6x->PCONR_f.OUTENA = pstcTimer6PortOutCfg->bOutEn;
+ TMR6x->PCONR_f.EMBVALA = pstcTimer6PortOutCfg->enDisVal;
+ break;
+
+ case Timer6PWMB:
+ TMR6x->PCONR_f.STACB = pstcTimer6PortOutCfg->enStaOut;
+ TMR6x->PCONR_f.STPCB = pstcTimer6PortOutCfg->enStpOut;
+ TMR6x->PCONR_f.STASTPSB = pstcTimer6PortOutCfg->enStaStp;
+ TMR6x->PCONR_f.CMPCB = pstcTimer6PortOutCfg->enCmpc;
+ TMR6x->PCONR_f.PERCB = pstcTimer6PortOutCfg->enPerc;
+ TMR6x->PCONR_f.OUTENB = pstcTimer6PortOutCfg->bOutEn;
+ TMR6x->PCONR_f.EMBVALB = pstcTimer6PortOutCfg->enDisVal;
+ break;
+
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+ return enRet;
+}
+
+
+/*******************************************************************************
+ * \brief Timer6 unit Set DeadTime Register Value(for PWM output)
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6DTReg DeadTime Register name
+ * \param [in] u16DTValue DeadTime Register value
+ *
+ * \retval Ok: Set Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SetDeadTimeValue(M4_TMR6_TypeDef *TMR6x, en_timer6_dead_time_reg_t enTimer6DTReg, uint16_t u16DTValue)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_DEAD_TIME_TYPE(enTimer6DTReg));
+
+ switch (enTimer6DTReg)
+ {
+ case Timer6DeadTimUpAR:
+ TMR6x->DTUAR = u16DTValue;
+ break;
+ case Timer6DeadTimUpBR:
+ TMR6x->DTUBR = u16DTValue;
+ break;
+ case Timer6DeadTimDwnAR:
+ TMR6x->DTDAR = u16DTValue;
+ break;
+ case Timer6DeadTimDwnBR:
+ TMR6x->DTDBR = u16DTValue;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Config DeadTime function
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] pstcTimer6DTCfg Timer6 dead time config pointer
+ *
+ * \retval Ok: Set Successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_ConfigDeadTime(M4_TMR6_TypeDef *TMR6x, const stc_timer6_deadtime_cfg_t* pstcTimer6DTCfg)
+{
+ en_result_t enRet = Ok;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ if (NULL == pstcTimer6DTCfg)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ TMR6x->DCONR_f.SEPA = pstcTimer6DTCfg->bEnDtEqualUpDwn;
+ TMR6x->DCONR_f.DTBENU = pstcTimer6DTCfg->bEnDtBufUp;
+ TMR6x->DCONR_f.DTBEND = pstcTimer6DTCfg->bEnDtBufDwn;
+ TMR6x->DCONR_f.DTCEN = pstcTimer6DTCfg->bEnDeadtime;
+ }
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Config Software Synchrony Start
+ *
+ *
+ * \param [in] pstcTimer6SwSyncStart Software Synchrony Start Pointer
+ *
+ * \retval Ok: Set successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SwSyncStart(const stc_timer6_sw_sync_t* pstcTimer6SwSyncStart)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32Val = 0ul;
+
+ if (NULL == pstcTimer6SwSyncStart)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ if (pstcTimer6SwSyncStart->bTimer61)
+ {
+ u32Val |= 0x1ul;
+ }
+ if (pstcTimer6SwSyncStart->bTimer62)
+ {
+ u32Val |= 0x2ul;
+ }
+ if (pstcTimer6SwSyncStart->bTimer63)
+ {
+ u32Val |= 0x4ul;
+ }
+
+ M4_TMR6_CR->SSTAR = u32Val;
+ }
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Config Software Synchrony Stop
+ *
+ *
+ * \param [in] pstcTimer6SwSyncStop Software Synchrony Stop Pointer
+ *
+ * \retval Ok: Set successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SwSyncStop(const stc_timer6_sw_sync_t* pstcTimer6SwSyncStop)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32Val = 0ul;
+
+ if (NULL == pstcTimer6SwSyncStop)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ if (pstcTimer6SwSyncStop->bTimer61)
+ {
+ u32Val |= 0x1ul;
+ }
+ if (pstcTimer6SwSyncStop->bTimer62)
+ {
+ u32Val |= 0x2ul;
+ }
+ if (pstcTimer6SwSyncStop->bTimer63)
+ {
+ u32Val |= 0x4ul;
+ }
+
+ M4_TMR6_CR->SSTPR = u32Val;
+ }
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Config Software Synchrony Clear
+ *
+ *
+ * \param [in] pstcTimer6SwSyncClear Software Synchrony Clear Pointer
+ *
+ * \retval Ok: Set successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_SwSyncClear(const stc_timer6_sw_sync_t* pstcTimer6SwSyncClear)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32Val = 0ul;
+
+ if (NULL == pstcTimer6SwSyncClear)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ if (pstcTimer6SwSyncClear->bTimer61)
+ {
+ u32Val |= 0x1ul;
+ }
+ if (pstcTimer6SwSyncClear->bTimer62)
+ {
+ u32Val |= 0x2ul;
+ }
+ if (pstcTimer6SwSyncClear->bTimer63)
+ {
+ u32Val |= 0x4ul;
+ }
+
+ M4_TMR6_CR->SCLRR = u32Val;
+ }
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Get Software Synchrony status
+ *
+ *
+ * \param [in] pstcTimer6SwSyncState Software Synchrony State Pointer
+ *
+ * \retval Ok: Set successfully
+ * \retval ErrorInvalidParameter: Provided parameter is not valid
+ *
+ ******************************************************************************/
+en_result_t Timer6_GetSwSyncState(stc_timer6_sw_sync_t* pstcTimer6SwSyncState)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcTimer6SwSyncState)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ if (M4_TMR6_CR->SSTAR & 0x1ul)
+ {
+ pstcTimer6SwSyncState->bTimer61 = true;
+ }
+ else
+ {
+ pstcTimer6SwSyncState->bTimer61 = false;
+ }
+ if (M4_TMR6_CR->SSTAR & 0x2ul)
+ {
+ pstcTimer6SwSyncState->bTimer62 = true;
+ }
+ else
+ {
+ pstcTimer6SwSyncState->bTimer62 = false;
+ }
+ if (M4_TMR6_CR->SSTAR & 0x4ul)
+ {
+ pstcTimer6SwSyncState->bTimer63 = true;
+ }
+ else
+ {
+ pstcTimer6SwSyncState->bTimer63 = false;
+ }
+ }
+
+ return enRet;
+}
+
+/*******************************************************************************
+ * \brief Timer6 Hardware UpCount Event config
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6HwCntUp Hardware UpCount Event
+ *
+ * \retval Ok: Set successfully
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_ConfigHwCntUp(M4_TMR6_TypeDef *TMR6x, en_timer6_hw_cnt_t enTimer6HwCntUp)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_HW_COUNT_TYPE(enTimer6HwCntUp));
+
+ u32Val = TMR6x->HCUPR;
+ TMR6x->HCUPR = u32Val | (1ul << enTimer6HwCntUp);
+
+ return Ok;
+}
+
+/**************************************************************
+ * \brief Clear Timer6 Hardware UpCount Event
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ************************************************************/
+en_result_t Timer6_ClearHwCntUp(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->HCUPR = 0ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Set Timer6 Hardware DownCount Event
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6HwCntDwn Hardware DownCount Event
+ *
+ * \retval Ok: Set successfully
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_ConfigHwCntDwn(M4_TMR6_TypeDef *TMR6x, en_timer6_hw_cnt_t enTimer6HwCntDwn)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_HW_COUNT_TYPE(enTimer6HwCntDwn));
+
+ u32Val = TMR6x->HCDOR;
+ TMR6x->HCDOR = u32Val | (1ul << enTimer6HwCntDwn);
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Clear Timer6 Hardware DownCount Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ClearHwCntDwn(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->HCDOR = 0ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Config Hardware Start Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6HwStart Hardware Start Event
+ *
+ * \retval Ok: Set successfully
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_ConfigHwStart(M4_TMR6_TypeDef *TMR6x, en_timer6_hw_trig_t enTimer6HwStart)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_HW_STA_STP_CLR_CAP_TYPE(enTimer6HwStart));
+
+ u32Val = TMR6x->HSTAR;
+ TMR6x->HSTAR = u32Val | (1ul << enTimer6HwStart);
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Clear Hardware Start Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ClearHwStart(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->HSTAR = 0ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Enable Hardware Start Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_EnableHwStart(M4_TMR6_TypeDef *TMR6x)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ u32Val = TMR6x->HSTAR;
+ TMR6x->HSTAR = u32Val | (1ul << 31u);
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Disable Hardware Start Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_DisableHwStart(M4_TMR6_TypeDef *TMR6x)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ u32Val = TMR6x->HSTAR;
+ TMR6x->HSTAR = u32Val & 0x7FFFFFFFul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Config Hardware Stop Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6HwStop Hardware Stop Event
+ *
+ * \retval Ok: Set successfully
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_ConfigHwStop(M4_TMR6_TypeDef *TMR6x, en_timer6_hw_trig_t enTimer6HwStop)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_HW_STA_STP_CLR_CAP_TYPE(enTimer6HwStop));
+
+ u32Val = TMR6x->HSTPR;
+ TMR6x->HSTPR = u32Val | (1ul << enTimer6HwStop);
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Clear Hardware Stop Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ClearHwStop(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->HSTPR = 0ul;
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Enable Hardware Stop Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_EnableHwStop(M4_TMR6_TypeDef *TMR6x)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ u32Val = TMR6x->HSTPR;
+ TMR6x->HSTPR = u32Val | (1ul << 31u);
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Disable Hardware Stop Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_DisableHwStop(M4_TMR6_TypeDef *TMR6x)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ u32Val = TMR6x->HSTPR;
+ TMR6x->HSTPR = u32Val & 0x7FFFFFFFul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Config Hardware Clear Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6HwClear Hardware Clear Event
+ *
+ * \retval Ok: Set successfully
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_ConfigHwClear(M4_TMR6_TypeDef *TMR6x, en_timer6_hw_trig_t enTimer6HwClear)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_HW_STA_STP_CLR_CAP_TYPE(enTimer6HwClear));
+
+ u32Val = TMR6x->HCLRR;
+ TMR6x->HCLRR = u32Val | (1ul << enTimer6HwClear);
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Clear Hardware Clear Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ClearHwClear(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->HCLRR = 0ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Enable Hardware Clear Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_EnableHwClear(M4_TMR6_TypeDef *TMR6x)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ u32Val = TMR6x->HCLRR;
+ TMR6x->HCLRR = u32Val | (1ul << 31u);
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Disable Hardware Clear Event
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_DisableHwClear(M4_TMR6_TypeDef *TMR6x)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ u32Val = TMR6x->HCLRR;
+ TMR6x->HCLRR = u32Val & 0x7FFFFFFFul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Config Hardware Capture Event A
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6HwCaptureA Hardware capture event A selection
+ *
+ * \retval Ok: Set successfully
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_ConfigHwCaptureA(M4_TMR6_TypeDef *TMR6x, en_timer6_hw_trig_t enTimer6HwCaptureA)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_HW_STA_STP_CLR_CAP_TYPE(enTimer6HwCaptureA));
+
+ u32Val = TMR6x->HCPAR;
+ TMR6x->HCPAR = u32Val | (1ul << enTimer6HwCaptureA);
+ //TMR6x->PCONR_f.CAPMDA = 1;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Clear Hardware Capture Event A
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ClearHwCaptureA(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->HCPAR = 0ul;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Config Hardware Capture Event B
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6HwCaptureB Hardware capture event B selection
+ *
+ * \retval Ok: Set successfully
+ * \note Please make sure that peripheral clock of M4_TMR61 is valid if The
+ * TRIGX pin is used.
+ ******************************************************************************/
+en_result_t Timer6_ConfigHwCaptureB(M4_TMR6_TypeDef *TMR6x, en_timer6_hw_trig_t enTimer6HwCaptureB)
+{
+ uint32_t u32Val;
+
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_HW_STA_STP_CLR_CAP_TYPE(enTimer6HwCaptureB));
+
+ u32Val = TMR6x->HCPBR;
+ TMR6x->HCPBR = u32Val | (1ul << enTimer6HwCaptureB);
+ //TMR6x->PCONR_f.CAPMDB = 1;
+
+ return Ok;
+}
+
+/*******************************************************************************
+ * \brief Clear Hardware Capture Event B
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ClearHwCaptureB(M4_TMR6_TypeDef *TMR6x)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+
+ TMR6x->HCPBR = 0ul;
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set trigger source 0 of hardware event
+ **
+ ** \param [in] enTriggerSrc Counter event trigger source
+ ** \arg 0-511 Used to trigger counter start/stop/clear/increment/decrement/capture
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t Timer6_SetTriggerSrc0(en_event_src_t enTriggerSrc)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EVENT_SOURCE(enTriggerSrc));
+
+ M4_AOS->TMR6_HTSSR0_f.TRGSEL = enTriggerSrc;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set trigger source 1 of hardware event
+ **
+ ** \param [in] enTriggerSrc Counter event trigger source
+ ** \arg 0-511 Used to trigger counter start/stop/clear/increment/decrement/capture
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t Timer6_SetTriggerSrc1(en_event_src_t enTriggerSrc)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EVENT_SOURCE(enTriggerSrc));
+
+ M4_AOS->TMR6_HTSSR1_f.TRGSEL = enTriggerSrc;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timer6 common trigger for hardware trigger register 0
+ **
+ ** \param [in] enComTrigger Timer0 common trigger selection. See @ref en_timer6_com_trigger_t for details.
+ ** \param [in] enState Enable or disable the specified common trigger.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void TIMER6_ComTriggerCmd0(en_timer6_com_trigger_t enComTrigger, en_functional_state_t enState)
+{
+ uint32_t u32ComTrig = (uint32_t)enComTrigger;
+
+ DDL_ASSERT(IS_VALID_TIMER6_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (enState == Enable)
+ {
+ M4_AOS->TMR6_HTSSR0 |= (u32ComTrig << 30u);
+ }
+ else
+ {
+ M4_AOS->TMR6_HTSSR0 &= ~(u32ComTrig << 30u);
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timer6 common trigger for hardware trigger register 1
+ **
+ ** \param [in] enComTrigger Timer0 common trigger selection. See @ref en_timer6_com_trigger_t for details.
+ ** \param [in] enState Enable or disable the specified common trigger.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+void TIMER6_ComTriggerCmd1(en_timer6_com_trigger_t enComTrigger, en_functional_state_t enState)
+{
+ uint32_t u32ComTrig = (uint32_t)enComTrigger;
+
+ DDL_ASSERT(IS_VALID_TIMER6_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
+
+ if (enState == Enable)
+ {
+ M4_AOS->TMR6_HTSSR1 |= (u32ComTrig << 30u);
+ }
+ else
+ {
+ M4_AOS->TMR6_HTSSR1 &= ~(u32ComTrig << 30u);
+ }
+}
+
+/*******************************************************************************
+ * \brief Z phase input mask config
+ *
+ *
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] pstcTimer6ZMaskCfg Z phase input mask config pointer
+ *
+ * \retval Ok: Set successfully
+ *
+ ******************************************************************************/
+en_result_t Timer6_ConfigZMask(M4_TMR6_TypeDef *TMR6x, const stc_timer6_zmask_cfg_t* pstcTimer6ZMaskCfg)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_ZPHASE_MASK_PRD(pstcTimer6ZMaskCfg->enZMaskCycle));
+
+ TMR6x->GCONR_f.ZMSKVAL = pstcTimer6ZMaskCfg->enZMaskCycle;
+ TMR6x->GCONR_f.ZMSKPOS = pstcTimer6ZMaskCfg->bFltPosCntMaksEn;
+ TMR6x->GCONR_f.ZMSKREV = pstcTimer6ZMaskCfg->bFltRevCntMaksEn;
+
+ return Ok;
+}
+
+
+//@} // Timer6Group
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_timera.c b/lib/hc32f460/driver/src/hc32f460_timera.c new file mode 100644 index 00000000..3f9a213b --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_timera.c @@ -0,0 +1,1968 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_timera.c
+ **
+ ** A detailed description is available at
+ ** @link TimeraGroup Timer A description @endlink
+ **
+ ** - 2018-11-08 CDT First version for Device Driver Library of
+ ** Timera.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_timera.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup TimeraGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for normal timera unit */
+#define IS_VALID_NORMAL_TIMERA_UNIT(x) \
+( (M4_TMRA1 == (x)) || \
+ (M4_TMRA2 == (x)) || \
+ (M4_TMRA3 == (x)) || \
+ (M4_TMRA4 == (x)) || \
+ (M4_TMRA5 == (x)) || \
+ (M4_TMRA6 == (x)))
+
+/*!< Parameter valid check for sync startup timera unit */
+#define IS_VALID_SYNC_STARTUP_TIMERA_UNIT(x) \
+( (M4_TMRA2 == (x)) || \
+ (M4_TMRA3 == (x)) || \
+ (M4_TMRA4 == (x)) || \
+ (M4_TMRA5 == (x)) || \
+ (M4_TMRA6 == (x)))
+
+/*!< Parameter valid check for Count clock division */
+#define IS_VALID_COUNT_CLK_DIV(x) \
+( (TimeraPclkDiv1 == (x)) || \
+ (TimeraPclkDiv2 == (x)) || \
+ (TimeraPclkDiv4 == (x)) || \
+ (TimeraPclkDiv8 == (x)) || \
+ (TimeraPclkDiv16 == (x)) || \
+ (TimeraPclkDiv32 == (x)) || \
+ (TimeraPclkDiv64 == (x)) || \
+ (TimeraPclkDiv128 == (x)) || \
+ (TimeraPclkDiv256 == (x)) || \
+ (TimeraPclkDiv512 == (x)) || \
+ (TimeraPclkDiv1024 == (x)))
+
+/*!< Parameter valid check for count mode */
+#define IS_VALID_COUNT_MODE(x) \
+( (TimeraCountModeSawtoothWave == (x)) || \
+ (TimeraCountModeTriangularWave == (x)))
+
+/*!< Parameter valid check for count direction */
+#define IS_VALID_COUNT_DIR(x) \
+( (TimeraCountDirUp == (x)) || \
+ (TimeraCountDirDown == (x)))
+
+/*!< Parameter valid check for normal timera channel */
+#define IS_VALID_NORMAL_TIMERA_CHANNEL(x) \
+( (TimeraCh1 == (x)) || \
+ (TimeraCh2 == (x)) || \
+ (TimeraCh3 == (x)) || \
+ (TimeraCh4 == (x)) || \
+ (TimeraCh5 == (x)) || \
+ (TimeraCh6 == (x)) || \
+ (TimeraCh7 == (x)) || \
+ (TimeraCh8 == (x)))
+
+/*!< Parameter valid check for set cache channel */
+#define IS_VALID_SET_CACHE_CHANNEL(x) \
+( (TimeraCh1 == (x)) || \
+ (TimeraCh3 == (x)) || \
+ (TimeraCh5 == (x)) || \
+ (TimeraCh7 == (x)))
+
+/*!< Parameter valid check for enable cache channel */
+#define IS_VALID_ENABLE_CACHE_CHANNEL(x) \
+( (TimeraCh1 == (x)) || \
+ (TimeraCh3 == (x)) || \
+ (TimeraCh5 == (x)) || \
+ (TimeraCh7 == (x)))
+
+/*!< Parameter valid check for timera count start output status */
+#define IS_VALID_COUNT_START_OUTPUT(x) \
+( (TimeraCountStartOutputLow == (x)) || \
+ (TimeraCountStartOutputHigh == (x)) || \
+ (TimeraCountStartOutputKeep == (x)))
+
+/*!< Parameter valid check for timera count stop output status */
+#define IS_VALID_COUNT_STOP_OUTPUT(x) \
+( (TimeraCountStopOutputLow == (x)) || \
+ (TimeraCountStopOutputHigh == (x)) || \
+ (TimeraCountStopOutputKeep == (x)))
+
+/*!< Parameter valid check for compare match output status */
+#define IS_VALID_COMPARE_MATCH_OUTPUT(x) \
+( (TimeraCompareMatchOutputLow == (x)) || \
+ (TimeraCompareMatchOutputHigh == (x)) || \
+ (TimeraCompareMatchOutputKeep == (x)) || \
+ (TimeraCompareMatchOutputReverse == (x)))
+
+/*!< Parameter valid check for period match output status */
+#define IS_VALID_PERIOD_MATCH_OUTPUT(x) \
+( (TimeraPeriodMatchOutputLow == (x)) || \
+ (TimeraPeriodMatchOutputHigh == (x)) || \
+ (TimeraPeriodMatchOutputKeep == (x)) || \
+ (TimeraPeriodMatchOutputReverse == (x)))
+
+/*!< Parameter valid check for specify output status */
+#define IS_VALID_SPECIFY_OUTPUT_STATUS(x) \
+( (TimeraSpecifyOutputInvalid == (x)) || \
+ (TimeraSpecifyOutputLow == (x)) || \
+ (TimeraSpecifyOutputHigh == (x)))
+
+/*!< Parameter valid check for port filter clock */
+#define IS_VALID_PORT_FILTER_CLOCK(x) \
+( (TimeraFilterPclkDiv1 == (x)) || \
+ (TimeraFilterPclkDiv4 == (x)) || \
+ (TimeraFilterPclkDiv16 == (x)) || \
+ (TimeraFilterPclkDiv64 == (x)))
+
+/*!< Parameter valid check for capture filter port source */
+#define IS_VALID_CAPTURE_FILTER_PORT_SOURCE(x) \
+( (TimeraFilterSourceCh1 == (x)) || \
+ (TimeraFilterSourceCh2 == (x)) || \
+ (TimeraFilterSourceCh3 == (x)) || \
+ (TimeraFilterSourceCh4 == (x)) || \
+ (TimeraFilterSourceCh5 == (x)) || \
+ (TimeraFilterSourceCh6 == (x)) || \
+ (TimeraFilterSourceCh7 == (x)) || \
+ (TimeraFilterSourceCh8 == (x)) || \
+ (TimeraFilterSourceTrig == (x)))
+
+/*!< Parameter valid check for coding filter port source */
+#define IS_VALID_CODING_FILTER_PORT_SOURCE(x) \
+( (TimeraFilterSourceClkA == (x)) || \
+ (TimeraFilterSourceClkB == (x)) || \
+ (TimeraFilterSourceTrig == (x)))
+
+/*!< Parameter valid check for interrupt request source */
+#define IS_VALID_IRQ_SOURCE(x) \
+( (TimeraIrqCaptureOrCompareCh1 == (x)) || \
+ (TimeraIrqCaptureOrCompareCh2 == (x)) || \
+ (TimeraIrqCaptureOrCompareCh3 == (x)) || \
+ (TimeraIrqCaptureOrCompareCh4 == (x)) || \
+ (TimeraIrqCaptureOrCompareCh5 == (x)) || \
+ (TimeraIrqCaptureOrCompareCh6 == (x)) || \
+ (TimeraIrqCaptureOrCompareCh7 == (x)) || \
+ (TimeraIrqCaptureOrCompareCh8 == (x)) || \
+ (TimeraIrqOverflow == (x)) || \
+ (TimeraIrqUnderflow == (x)))
+
+/*!< Parameter valid check for flag type */
+#define IS_VALID_FLAG_TYPE(x) \
+( (TimeraFlagCaptureOrCompareCh1 == (x)) || \
+ (TimeraFlagCaptureOrCompareCh2 == (x)) || \
+ (TimeraFlagCaptureOrCompareCh3 == (x)) || \
+ (TimeraFlagCaptureOrCompareCh4 == (x)) || \
+ (TimeraFlagCaptureOrCompareCh5 == (x)) || \
+ (TimeraFlagCaptureOrCompareCh6 == (x)) || \
+ (TimeraFlagCaptureOrCompareCh7 == (x)) || \
+ (TimeraFlagCaptureOrCompareCh8 == (x)) || \
+ (TimeraFlagOverflow == (x)) || \
+ (TimeraFlagUnderflow == (x)))
+
+/*! Parameter valid check for common trigger. */
+#define IS_VALID_COM_TRIGGER(x) \
+( (TimeraComTrigger_1 == (x)) || \
+ (TimeraComTrigger_2 == (x)) || \
+ (TimeraComTrigger_1_2 == (x)))
+
+/*!< Parameter valid check for event source */
+#define IS_VALID_EVENT_SOURCE(x) ((x) <= 511u)
+
+/*!< Timera registers reset value */
+#define TIMERA_REG_CNTER_RESET_VALUE (0x0000u)
+#define TIMERA_REG_PERAR_RESET_VALUE (0xFFFFu)
+#define TIMERA_REG_CMPAR_RESET_VALUE (0xFFFFu)
+#define TIMERA_REG_BCSTR_RESET_VALUE (0x0002u)
+#define TIMERA_REG_ICONR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_ECONR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_FCONR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_STFLR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_BCONR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_CCONR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_PCONR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_HCONR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_HCUPR_RESET_VALUE (0x0000u)
+#define TIMERA_REG_HCDOR_RESET_VALUE (0x0000u)
+
+#define TIMERA_REG_HTSSR0_RESET_VALUE (0x000001FFul)
+#define TIMERA_REG_HTSSR1_RESET_VALUE (0x000001FFul)
+
+/*!< Timera calculate register address of channel */
+#define TIMERA_CALC_REG_ADDR(reg, chl) ((uint32_t)(&(reg)) + (chl)*0x4u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief De-Initialize Timera unit
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_DeInit(M4_TMRA_TypeDef *TIMERAx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint32_t u32Cnt = 0u;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ TIMERAx->CNTER = TIMERA_REG_CNTER_RESET_VALUE;
+ TIMERAx->PERAR = TIMERA_REG_PERAR_RESET_VALUE;
+ TIMERAx->BCSTR = TIMERA_REG_BCSTR_RESET_VALUE;
+ TIMERAx->ICONR = TIMERA_REG_ICONR_RESET_VALUE;
+ TIMERAx->ECONR = TIMERA_REG_ECONR_RESET_VALUE;
+ TIMERAx->FCONR = TIMERA_REG_FCONR_RESET_VALUE;
+ TIMERAx->STFLR = TIMERA_REG_STFLR_RESET_VALUE;
+ TIMERAx->HCONR = TIMERA_REG_HCONR_RESET_VALUE;
+ TIMERAx->HCUPR = TIMERA_REG_HCUPR_RESET_VALUE;
+ TIMERAx->HCDOR = TIMERA_REG_HCDOR_RESET_VALUE;
+
+ for (u32Cnt = 0u; u32Cnt < 8u; u32Cnt++)
+ {
+ *(__IO uint16_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CMPAR1, u32Cnt) = TIMERA_REG_CMPAR_RESET_VALUE;
+ }
+ for (u32Cnt = 0u; u32Cnt < 4u; u32Cnt++)
+ {
+ *(__IO uint16_t *)TIMERA_CALC_REG_ADDR(TIMERAx->BCONR1, u32Cnt * 2u) = TIMERA_REG_BCONR_RESET_VALUE;
+ }
+ for (u32Cnt = 0u; u32Cnt < 8u; u32Cnt++)
+ {
+ *(__IO uint16_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CCONR1, u32Cnt) = TIMERA_REG_CCONR_RESET_VALUE;
+ }
+ for (u32Cnt = 0u; u32Cnt < 8u; u32Cnt++)
+ {
+ *(__IO uint16_t *)TIMERA_CALC_REG_ADDR(TIMERAx->PCONR1, u32Cnt) = TIMERA_REG_PCONR_RESET_VALUE;
+ }
+
+ M4_AOS->TMRA_HTSSR0 = TIMERA_REG_HTSSR0_RESET_VALUE;
+ M4_AOS->TMRA_HTSSR1 = TIMERA_REG_HTSSR1_RESET_VALUE;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize Timera unit base function
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] pstcBaseInit Pointer to timera base init configuration
+ ** \arg See the struct #stc_timera_base_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidMode Unit 1 sync startup invalid
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcBaseInit == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMERA_BaseInit(M4_TMRA_TypeDef *TIMERAx, const stc_timera_base_init_t *pstcBaseInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcBaseInit))
+ {
+ DDL_ASSERT(IS_VALID_COUNT_CLK_DIV(pstcBaseInit->enClkDiv));
+ DDL_ASSERT(IS_VALID_COUNT_MODE(pstcBaseInit->enCntMode));
+ DDL_ASSERT(IS_VALID_COUNT_DIR(pstcBaseInit->enCntDir));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcBaseInit->enSyncStartupEn));
+
+ /* Configure control status register */
+ TIMERAx->BCSTR_f.CKDIV = pstcBaseInit->enClkDiv;
+ TIMERAx->BCSTR_f.MODE = pstcBaseInit->enCntMode;
+ TIMERAx->BCSTR_f.DIR = pstcBaseInit->enCntDir;
+
+ /* Unit 1 sync startup invalid */
+ if ((M4_TMRA1 == TIMERAx) && (Enable == pstcBaseInit->enSyncStartupEn))
+ {
+ enRet = ErrorInvalidMode;
+ }
+ else
+ {
+ TIMERAx->BCSTR_f.SYNST = pstcBaseInit->enSyncStartupEn;
+ enRet = Ok;
+ }
+
+ /* Configure period value register */
+ TIMERAx->PERAR = pstcBaseInit->u16PeriodVal;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timera current count value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] u16Cnt Timera current count value
+ ** \arg 0-0xFFFF
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SetCurrCount(M4_TMRA_TypeDef *TIMERAx, uint16_t u16Cnt)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ TIMERAx->CNTER = u16Cnt;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timera current count value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \retval uint16_t Timera current count value
+ **
+ ******************************************************************************/
+uint16_t TIMERA_GetCurrCount(M4_TMRA_TypeDef *TIMERAx)
+{
+ uint16_t u16CurrCntVal = 0u;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ u16CurrCntVal = (uint16_t)TIMERAx->CNTER;
+ }
+
+ return u16CurrCntVal;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timera period value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] u16Period Timera period value
+ ** \arg 0-0xFFFF
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SetPeriodValue(M4_TMRA_TypeDef *TIMERAx, uint16_t u16Period)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ TIMERAx->PERAR = u16Period;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timera period count value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \retval uint16_t Timera current period value
+ **
+ ******************************************************************************/
+uint16_t TIMERA_GetPeriodValue(M4_TMRA_TypeDef *TIMERAx)
+{
+ uint16_t u16PeriodVal = 0u;
+
+ /* Check parameters */
+ if (IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ u16PeriodVal = (uint16_t)TIMERAx->PERAR;
+ }
+
+ return u16PeriodVal;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera software synchronous startup
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable synchronous startup
+ ** \arg Enable Enable synchronous startup
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SyncStartupCmd(M4_TMRA_TypeDef *TIMERAx, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_SYNC_STARTUP_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ TIMERAx->BCSTR_f.SYNST = enNewSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera startup
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable timera startup
+ ** \arg Enable Enable timera startup
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_Cmd(M4_TMRA_TypeDef *TIMERAx, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ TIMERAx->BCSTR_f.START = enNewSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize Timera unit compare function
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera compare channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \param [in] pstcCompareInit Pointer to timera compare init configuration
+ ** \arg See the struct #stc_timera_compare_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcCompareInit == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMERA_CompareInit(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ const stc_timera_compare_init_t *pstcCompareInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_pconr_field_t *pstcTimeraPort;
+ __IO stc_tmra_bconr_field_t *pstcTimeraCache;
+ __IO stc_tmra_cmpar_field_t *pstcTimeraCompare;
+ __IO stc_tmra_cconr_field_t *pstcTimeraCapture;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcCompareInit))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+ DDL_ASSERT(IS_VALID_COUNT_START_OUTPUT(pstcCompareInit->enStartCountOutput));
+ DDL_ASSERT(IS_VALID_COUNT_STOP_OUTPUT(pstcCompareInit->enStopCountOutput));
+ DDL_ASSERT(IS_VALID_COMPARE_MATCH_OUTPUT(pstcCompareInit->enCompareMatchOutput));
+ DDL_ASSERT(IS_VALID_PERIOD_MATCH_OUTPUT(pstcCompareInit->enPeriodMatchOutput));
+ DDL_ASSERT(IS_VALID_SPECIFY_OUTPUT_STATUS(pstcCompareInit->enSpecifyOutput));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCompareInit->enCacheEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCompareInit->enTriangularCrestTransEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCompareInit->enTriangularTroughTransEn));
+
+ /* Configure port control register */
+ pstcTimeraPort = (stc_tmra_pconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->PCONR1, enChannel);
+ pstcTimeraPort->STAC = pstcCompareInit->enStartCountOutput;
+ pstcTimeraPort->STPC = pstcCompareInit->enStopCountOutput;
+ pstcTimeraPort->CMPC = pstcCompareInit->enCompareMatchOutput;
+ pstcTimeraPort->PERC = pstcCompareInit->enPeriodMatchOutput;
+ pstcTimeraPort->FORC = pstcCompareInit->enSpecifyOutput;
+
+ /* Configure cache control register */
+ if ((TimeraCh1 == enChannel) || (TimeraCh3 == enChannel) ||
+ (TimeraCh5 == enChannel) || (TimeraCh7 == enChannel))
+ {
+ pstcTimeraCache = (stc_tmra_bconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->BCONR1, enChannel);
+ pstcTimeraCache->BSE0 = pstcCompareInit->enTriangularCrestTransEn;
+ pstcTimeraCache->BSE1 = pstcCompareInit->enTriangularTroughTransEn;
+ pstcTimeraCache->BEN = pstcCompareInit->enCacheEn;
+ /* Configure compare cache value register */
+ pstcTimeraCompare = (stc_tmra_cmpar_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CMPAR1, enChannel + 1);
+ pstcTimeraCompare->CMP = pstcCompareInit->u16CompareCacheVal;
+ }
+
+ /* Configure compare value register */
+ pstcTimeraCompare = (stc_tmra_cmpar_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CMPAR1, enChannel);
+ pstcTimeraCompare->CMP = pstcCompareInit->u16CompareVal;
+
+ /* Set compare output function */
+ pstcTimeraCapture = (stc_tmra_cconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CCONR1, enChannel);
+ pstcTimeraCapture->CAPMD = 0u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timera compare value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera compare channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \param [in] u16CompareVal Timera campare value
+ ** \arg 0-0xFFFF
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SetCompareValue(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ uint16_t u16CompareVal)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_cmpar_field_t *pstcTimeraCompare;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+
+ pstcTimeraCompare = (stc_tmra_cmpar_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CMPAR1, enChannel);
+ pstcTimeraCompare->CMP = u16CompareVal;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timera compare value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera compare channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \retval uint16_t Timera compare value
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+uint16_t TIMERA_GetCompareValue(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel)
+{
+ uint16_t u16CompareVal = 0u;
+ __IO stc_tmra_cmpar_field_t *pstcTimeraCompare;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+
+ pstcTimeraCompare = (stc_tmra_cmpar_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CMPAR1, enChannel);
+ u16CompareVal = (uint16_t)pstcTimeraCompare->CMP;
+ }
+
+ return u16CompareVal;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timera compare cache value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera compare channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh7 Timera channel 7
+ **
+ ** \param [in] u16CompareCache Timera compare cache value
+ ** \arg 0-0xFFFF
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SetCacheValue(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ uint16_t u16CompareCache)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_cmpar_field_t *pstcTimeraCompare;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_SET_CACHE_CHANNEL(enChannel));
+
+ pstcTimeraCompare = (stc_tmra_cmpar_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CMPAR1, enChannel + 1);
+ pstcTimeraCompare->CMP = u16CompareCache;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera compare cache
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera compare channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh7 Timera channel 7
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable timera compare cache
+ ** \arg Enable Enable timera compare cache
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_CompareCacheCmd(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_bconr_field_t *pstcTimeraCache;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_ENABLE_CACHE_CHANNEL(enChannel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ /* Configure cache control register */
+ pstcTimeraCache = (stc_tmra_bconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->BCONR1, enChannel);
+ pstcTimeraCache->BEN = enNewSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Specify Timera port output status
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera compare channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \param [in] enOutputSta Timera port output status
+ ** \arg TimeraSpecifyOutputInvalid Port output invalid
+ ** \arg TimeraSpecifyOutputLow Port output low level from next period
+ ** \arg TimeraSpecifyOutputHigh Port output high level from next period
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SpecifyOutputSta(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ en_timera_specify_output_t enOutputSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_pconr_field_t *pstcTimeraPort;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+ DDL_ASSERT(IS_VALID_SPECIFY_OUTPUT_STATUS(enOutputSta));
+
+ pstcTimeraPort = (stc_tmra_pconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->PCONR1, enChannel);
+ pstcTimeraPort->FORC = enOutputSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera compare function
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera compare channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable timera compare function
+ ** \arg Enable Enable timera compare function
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_CompareCmd(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_pconr_field_t *pstcTimeraPort;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ pstcTimeraPort = (stc_tmra_pconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->PCONR1, enChannel);
+ pstcTimeraPort->OUTEN = enNewSta;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize Timera unit capture function
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera capture channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \param [in] pstcCapInit Pointer to timera capture init configuration
+ ** \arg See the struct #stc_timera_capture_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcCapInit == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMERA_CaptureInit(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ const stc_timera_capture_init_t *pstcCapInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_cconr_field_t *pstcTimeraCapture;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcCapInit))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCapInit->enCapturePwmRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCapInit->enCapturePwmFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCapInit->enCaptureSpecifyEventEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCapInit->enCaptureTrigFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCapInit->enCaptureTrigRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCapInit->enPwmFilterEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCapInit->enTrigFilterEn));
+ DDL_ASSERT(IS_VALID_PORT_FILTER_CLOCK(pstcCapInit->enPwmClkDiv));
+ DDL_ASSERT(IS_VALID_PORT_FILTER_CLOCK(pstcCapInit->enTrigClkDiv));
+
+ /* Configure capture control register */
+ pstcTimeraCapture = (stc_tmra_cconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CCONR1, enChannel);
+ pstcTimeraCapture->HICP0 = pstcCapInit->enCapturePwmRisingEn;
+ pstcTimeraCapture->HICP1 = pstcCapInit->enCapturePwmFallingEn;
+ pstcTimeraCapture->HICP2 = pstcCapInit->enCaptureSpecifyEventEn;
+ pstcTimeraCapture->NOFICKCP = pstcCapInit->enPwmClkDiv;
+ pstcTimeraCapture->NOFIENCP = pstcCapInit->enPwmFilterEn;
+
+ /* TIMA_<t>_TRIG port capture function only valid for TimeraCh3 */
+ if (TimeraCh3 == enChannel)
+ {
+ pstcTimeraCapture->HICP3 = pstcCapInit->enCaptureTrigRisingEn;
+ pstcTimeraCapture->HICP4 = pstcCapInit->enCaptureTrigFallingEn;
+ /* Configure filter control register */
+ TIMERAx->FCONR_f.NOFICKTG = pstcCapInit->enTrigClkDiv;
+ TIMERAx->FCONR_f.NOFIENTG = pstcCapInit->enTrigFilterEn;
+ }
+
+ /* Set capture input function */
+ pstcTimeraCapture->CAPMD = 1u;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera capture filter
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enFilterPort Timera capture filter input port
+ ** \arg TimeraFilterSourceCh1 TIMA_<t>_PWM1 input port
+ ** \arg TimeraFilterSourceCh2 TIMA_<t>_PWM2 input port
+ ** \arg TimeraFilterSourceCh3 TIMA_<t>_PWM3 input port
+ ** \arg TimeraFilterSourceCh4 TIMA_<t>_PWM4 input port
+ ** \arg TimeraFilterSourceCh5 TIMA_<t>_PWM5 input port
+ ** \arg TimeraFilterSourceCh6 TIMA_<t>_PWM6 input port
+ ** \arg TimeraFilterSourceCh7 TIMA_<t>_PWM7 input port
+ ** \arg TimeraFilterSourceCh8 TIMA_<t>_PWM8 input port
+ ** \arg TimeraFilterSourceTrig TIMA_<t>_TRIG input port
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable timera capture filter
+ ** \arg Enable Enable timera capture filter
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_CaptureFilterCmd(M4_TMRA_TypeDef *TIMERAx, en_timera_filter_source_t enFilterPort,
+ en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO stc_tmra_cconr_field_t *pstcTimeraCapture;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_CAPTURE_FILTER_PORT_SOURCE(enFilterPort));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ if (TimeraFilterSourceTrig == enFilterPort)
+ {
+ TIMERAx->FCONR_f.NOFIENTG = enNewSta;
+ }
+ else
+ {
+ pstcTimeraCapture = (stc_tmra_cconr_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CCONR1, enFilterPort);
+ pstcTimeraCapture->NOFIENCP = enNewSta;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timera capture value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera capture channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \retval uint16_t Timera capture value
+ **
+ ******************************************************************************/
+uint16_t TIMERA_GetCaptureValue(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel)
+{
+ uint16_t u16CapVal = 0u;
+ __IO stc_tmra_cmpar_field_t *pstcTimeraCompare;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+
+ pstcTimeraCompare = (stc_tmra_cmpar_field_t *)TIMERA_CALC_REG_ADDR(TIMERAx->CMPAR1, enChannel);
+ u16CapVal = (uint16_t)pstcTimeraCompare->CMP;
+ }
+
+ return u16CapVal;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize Timera unit orthogonal coding function
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] pstcCodingInit Pointer to timera orthogonal coding configuration
+ ** \arg See the struct #stc_timera_orthogonal_coding_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcCodingInit == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMERA_OrthogonalCodingInit(M4_TMRA_TypeDef *TIMERAx, const stc_timera_orthogonal_coding_init_t *pstcCodingInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcCodingInit))
+ {
+ DDL_ASSERT(IS_VALID_PORT_FILTER_CLOCK(pstcCodingInit->enTrigClkDiv));
+ DDL_ASSERT(IS_VALID_PORT_FILTER_CLOCK(pstcCodingInit->enClkBClkDiv));
+ DDL_ASSERT(IS_VALID_PORT_FILTER_CLOCK(pstcCodingInit->enClkAClkDiv));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enTrigFilterEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enClkBFilterEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enClkAFilterEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkALowAndClkBRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkALowAndClkBFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkAHighAndClkBRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkAHighAndClkBFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkBLowAndClkARisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkBLowAndClkAFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkBHighAndClkARisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncClkBHighAndClkAFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncTrigRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncTrigFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncSpecifyEventTriggerEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncAnotherUnitOverflowEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enIncAnotherUnitUnderflowEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkALowAndClkBRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkALowAndClkBFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkAHighAndClkBRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkAHighAndClkBFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkBLowAndClkARisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkBLowAndClkAFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkBHighAndClkARisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecClkBHighAndClkAFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecTrigRisingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecTrigFallingEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecSpecifyEventTriggerEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecAnotherUnitOverflowEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCodingInit->enDecAnotherUnitUnderflowEn));
+
+ /* Configure hardware increase event register */
+ TIMERAx->HCUPR_f.HCUP0 = pstcCodingInit->enIncClkALowAndClkBRisingEn;
+ TIMERAx->HCUPR_f.HCUP1 = pstcCodingInit->enIncClkALowAndClkBFallingEn;
+ TIMERAx->HCUPR_f.HCUP2 = pstcCodingInit->enIncClkAHighAndClkBRisingEn;
+ TIMERAx->HCUPR_f.HCUP3 = pstcCodingInit->enIncClkAHighAndClkBFallingEn;
+ TIMERAx->HCUPR_f.HCUP4 = pstcCodingInit->enIncClkBLowAndClkARisingEn;
+ TIMERAx->HCUPR_f.HCUP5 = pstcCodingInit->enIncClkBLowAndClkAFallingEn;
+ TIMERAx->HCUPR_f.HCUP6 = pstcCodingInit->enIncClkBHighAndClkARisingEn;
+ TIMERAx->HCUPR_f.HCUP7 = pstcCodingInit->enIncClkBHighAndClkAFallingEn;
+ TIMERAx->HCUPR_f.HCUP8 = pstcCodingInit->enIncTrigRisingEn;
+ TIMERAx->HCUPR_f.HCUP9 = pstcCodingInit->enIncTrigFallingEn;
+ TIMERAx->HCUPR_f.HCUP10 = pstcCodingInit->enIncSpecifyEventTriggerEn;
+ TIMERAx->HCUPR_f.HCUP11 = pstcCodingInit->enIncAnotherUnitOverflowEn;
+ TIMERAx->HCUPR_f.HCUP12 = pstcCodingInit->enIncAnotherUnitUnderflowEn;
+
+ /* Configure hardware decrease event register */
+ TIMERAx->HCDOR_f.HCDO0 = pstcCodingInit->enDecClkALowAndClkBRisingEn;
+ TIMERAx->HCDOR_f.HCDO1 = pstcCodingInit->enDecClkALowAndClkBFallingEn;
+ TIMERAx->HCDOR_f.HCDO2 = pstcCodingInit->enDecClkAHighAndClkBRisingEn;
+ TIMERAx->HCDOR_f.HCDO3 = pstcCodingInit->enDecClkAHighAndClkBFallingEn;
+ TIMERAx->HCDOR_f.HCDO4 = pstcCodingInit->enDecClkBLowAndClkARisingEn;
+ TIMERAx->HCDOR_f.HCDO5 = pstcCodingInit->enDecClkBLowAndClkAFallingEn;
+ TIMERAx->HCDOR_f.HCDO6 = pstcCodingInit->enDecClkBHighAndClkARisingEn;
+ TIMERAx->HCDOR_f.HCDO7 = pstcCodingInit->enDecClkBHighAndClkAFallingEn;
+ TIMERAx->HCDOR_f.HCDO8 = pstcCodingInit->enDecTrigRisingEn;
+ TIMERAx->HCDOR_f.HCDO9 = pstcCodingInit->enDecTrigFallingEn;
+ TIMERAx->HCDOR_f.HCDO10 = pstcCodingInit->enDecSpecifyEventTriggerEn;
+ TIMERAx->HCDOR_f.HCDO11 = pstcCodingInit->enDecAnotherUnitOverflowEn;
+ TIMERAx->HCDOR_f.HCDO12 = pstcCodingInit->enDecAnotherUnitUnderflowEn;
+
+ /* Configure filter control register */
+ TIMERAx->FCONR_f.NOFICKTG = pstcCodingInit->enTrigClkDiv;
+ TIMERAx->FCONR_f.NOFIENTG = pstcCodingInit->enTrigFilterEn;
+ TIMERAx->FCONR_f.NOFICKCB = pstcCodingInit->enClkBClkDiv;
+ TIMERAx->FCONR_f.NOFIENCB = pstcCodingInit->enClkBFilterEn;
+ TIMERAx->FCONR_f.NOFICKCA = pstcCodingInit->enClkAClkDiv;
+ TIMERAx->FCONR_f.NOFIENCA = pstcCodingInit->enClkAFilterEn;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set Timera orthogonal coding value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] u16CodingCnt Timera orthogonal coding value
+ ** \arg 0-0xFFFF
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SetOrthogonalCodingCount(M4_TMRA_TypeDef *TIMERAx, uint16_t u16CodingCnt)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ TIMERAx->CNTER = u16CodingCnt;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timera orthogonal coding value
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \retval uint16_t Timera orthogonal coding value
+ **
+ ******************************************************************************/
+uint16_t TIMERA_GetOrthogonalCodingCount(M4_TMRA_TypeDef *TIMERAx)
+{
+ uint16_t u16CodingCnt = 0u;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ u16CodingCnt = (uint16_t)TIMERAx->CNTER;
+ }
+
+ return u16CodingCnt;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera orthogonal coding filter
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enFilterPort Timera orthogonal coding filter input port
+ ** \arg TimeraFilterSourceClkA TIMA_<t>_CLKA input port
+ ** \arg TimeraFilterSourceClkB TIMA_<t>_CLKB input port
+ ** \arg TimeraFilterSourceTrig TIMA_<t>_TRIG input port
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable timera orthogonal coding filter
+ ** \arg Enable Enable timera orthogonal coding filter
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_OrthogonalCodingFilterCmd(M4_TMRA_TypeDef *TIMERAx, en_timera_filter_source_t enFilterPort,
+ en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_CODING_FILTER_PORT_SOURCE(enFilterPort));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ switch (enFilterPort)
+ {
+ case TimeraFilterSourceClkA:
+ TIMERAx->FCONR_f.NOFIENCA = enNewSta;
+ break;
+ case TimeraFilterSourceClkB:
+ TIMERAx->FCONR_f.NOFIENCB = enNewSta;
+ break;
+ case TimeraFilterSourceTrig:
+ TIMERAx->FCONR_f.NOFIENTG = enNewSta;
+ break;
+ default:
+ break;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize Timera unit hardware trigger event function
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] pstcHwTriggerInit Pointer to timera hardware trigger event configuration
+ ** \arg See the struct #stc_timera_hw_trigger_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcHwTriggerInit == NULL
+ **
+ ** \note If sync startup(BCSTR.SYNST) bit set 1 trigger hardware sync startup when HCONR.HSTA1~0 bit set
+ **
+ ******************************************************************************/
+en_result_t TIMERA_HwTriggerInit(M4_TMRA_TypeDef *TIMERAx, const stc_timera_hw_trigger_init_t *pstcHwTriggerInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcHwTriggerInit))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwStartup.enTrigRisingStartupEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwStartup.enTrigFallingStartupEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwStartup.enSpecifyEventStartupEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwStop.enTrigRisingStopEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwStop.enTrigFallingStopEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwStop.enSpecifyEventStopEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwClear.enTrigRisingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwClear.enTrigFallingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwClear.enSpecifyEventClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwClear.enAnotherUnitTrigRisingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwClear.enAnotherUnitTrigFallingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwClear.enChannel3RisingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwTriggerInit->stcHwClear.enChannel3FallingClearEn));
+
+ /* Configure hardware startup conditions */
+ TIMERAx->HCONR_f.HSTA0 = pstcHwTriggerInit->stcHwStartup.enTrigRisingStartupEn;
+ TIMERAx->HCONR_f.HSTA1 = pstcHwTriggerInit->stcHwStartup.enTrigFallingStartupEn;
+ TIMERAx->HCONR_f.HSTA2 = pstcHwTriggerInit->stcHwStartup.enSpecifyEventStartupEn;
+
+ /* Configure hardware stop conditions */
+ TIMERAx->HCONR_f.HSTP0 = pstcHwTriggerInit->stcHwStop.enTrigRisingStopEn;
+ TIMERAx->HCONR_f.HSTP1 = pstcHwTriggerInit->stcHwStop.enTrigFallingStopEn;
+ TIMERAx->HCONR_f.HSTP2 = pstcHwTriggerInit->stcHwStop.enSpecifyEventStopEn;
+
+ /* Configure hardware clear conditions */
+ TIMERAx->HCONR_f.HCLE0 = pstcHwTriggerInit->stcHwClear.enTrigRisingClearEn;
+ TIMERAx->HCONR_f.HCLE1 = pstcHwTriggerInit->stcHwClear.enTrigFallingClearEn;
+ TIMERAx->HCONR_f.HCLE2 = pstcHwTriggerInit->stcHwClear.enSpecifyEventClearEn;
+ TIMERAx->HCONR_f.HCLE3 = pstcHwTriggerInit->stcHwClear.enAnotherUnitTrigRisingClearEn;
+ TIMERAx->HCONR_f.HCLE4 = pstcHwTriggerInit->stcHwClear.enAnotherUnitTrigFallingClearEn;
+ TIMERAx->HCONR_f.HCLE5 = pstcHwTriggerInit->stcHwClear.enChannel3RisingClearEn;
+ TIMERAx->HCONR_f.HCLE6 = pstcHwTriggerInit->stcHwClear.enChannel3FallingClearEn;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Timera hardware startup Config
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] pstcHwStartup Pointer to timera hardware startup configuration
+ ** \arg See the struct #stc_timera_hw_startup_config_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcHwStartup == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMERA_HwStartupConfig(M4_TMRA_TypeDef *TIMERAx, const stc_timera_hw_startup_config_t *pstcHwStartup)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcHwStartup))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwStartup->enTrigRisingStartupEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwStartup->enTrigFallingStartupEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwStartup->enSpecifyEventStartupEn));
+
+ TIMERAx->HCONR_f.HSTA0 = pstcHwStartup->enTrigRisingStartupEn;
+ TIMERAx->HCONR_f.HSTA1 = pstcHwStartup->enTrigFallingStartupEn;
+ TIMERAx->HCONR_f.HSTA2 = pstcHwStartup->enSpecifyEventStartupEn;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Timera hardware stop Config
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] pstcHwStop Pointer to timera hardware stop configuration
+ ** \arg See the struct #stc_timera_hw_stop_config_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcHwStop == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMERA_HwStopConfig(M4_TMRA_TypeDef *TIMERAx, const stc_timera_hw_stop_config_t *pstcHwStop)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcHwStop))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwStop->enTrigRisingStopEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwStop->enTrigFallingStopEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwStop->enSpecifyEventStopEn));
+
+ TIMERAx->HCONR_f.HSTP0 = pstcHwStop->enTrigRisingStopEn;
+ TIMERAx->HCONR_f.HSTP1 = pstcHwStop->enTrigFallingStopEn;
+ TIMERAx->HCONR_f.HSTP2 = pstcHwStop->enSpecifyEventStopEn;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Timera hardware clear Config
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] pstcHwClear Pointer to timera hardware clear configuration
+ ** \arg See the struct #stc_timera_hw_clear_config_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ ** - pstcHwClear == NULL
+ **
+ ******************************************************************************/
+en_result_t TIMERA_HwClearConfig(M4_TMRA_TypeDef *TIMERAx, const stc_timera_hw_clear_config_t *pstcHwClear)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx) && (NULL != pstcHwClear))
+ {
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwClear->enTrigRisingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwClear->enTrigFallingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwClear->enSpecifyEventClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwClear->enAnotherUnitTrigRisingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwClear->enAnotherUnitTrigFallingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwClear->enChannel3RisingClearEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcHwClear->enChannel3FallingClearEn));
+
+ TIMERAx->HCONR_f.HCLE0 = pstcHwClear->enTrigRisingClearEn;
+ TIMERAx->HCONR_f.HCLE1 = pstcHwClear->enTrigFallingClearEn;
+ TIMERAx->HCONR_f.HCLE2 = pstcHwClear->enSpecifyEventClearEn;
+ TIMERAx->HCONR_f.HCLE3 = pstcHwClear->enAnotherUnitTrigRisingClearEn;
+ TIMERAx->HCONR_f.HCLE4 = pstcHwClear->enAnotherUnitTrigFallingClearEn;
+ TIMERAx->HCONR_f.HCLE5 = pstcHwClear->enChannel3RisingClearEn;
+ TIMERAx->HCONR_f.HCLE6 = pstcHwClear->enChannel3FallingClearEn;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera interrupt request
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enIrq Timera interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh1 Channel 1 interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh2 Channel 2 interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh3 Channel 3 interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh4 Channel 4 interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh5 Channel 5 interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh6 Channel 6 interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh7 Channel 7 interrupt request
+ ** \arg TimeraIrqCaptureOrCompareCh8 Channel 8 interrupt request
+ ** \arg TimeraIrqOverflow Count overflow interrupt request
+ ** \arg TimeraIrqUnderflow Count underflow interrupt request
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable timera interrupt request
+ ** \arg Enable Enable timera interrupt request
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_IrqCmd(M4_TMRA_TypeDef *TIMERAx, en_timera_irq_type_t enIrq,
+ en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_IRQ_SOURCE(enIrq));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ switch (enIrq)
+ {
+ case TimeraIrqCaptureOrCompareCh1:
+ TIMERAx->ICONR_f.ITEN1 = enNewSta;
+ break;
+ case TimeraIrqCaptureOrCompareCh2:
+ TIMERAx->ICONR_f.ITEN2 = enNewSta;
+ break;
+ case TimeraIrqCaptureOrCompareCh3:
+ TIMERAx->ICONR_f.ITEN3 = enNewSta;
+ break;
+ case TimeraIrqCaptureOrCompareCh4:
+ TIMERAx->ICONR_f.ITEN4 = enNewSta;
+ break;
+ case TimeraIrqCaptureOrCompareCh5:
+ TIMERAx->ICONR_f.ITEN5 = enNewSta;
+ break;
+ case TimeraIrqCaptureOrCompareCh6:
+ TIMERAx->ICONR_f.ITEN6 = enNewSta;
+ break;
+ case TimeraIrqCaptureOrCompareCh7:
+ TIMERAx->ICONR_f.ITEN7 = enNewSta;
+ break;
+ case TimeraIrqCaptureOrCompareCh8:
+ TIMERAx->ICONR_f.ITEN8 = enNewSta;
+ break;
+ case TimeraIrqOverflow:
+ TIMERAx->BCSTR_f.ITENOVF = enNewSta;
+ break;
+ case TimeraIrqUnderflow:
+ TIMERAx->BCSTR_f.ITENUDF = enNewSta;
+ break;
+ default:
+ break;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable Timera event request
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enChannel Timera event request channel
+ ** \arg TimeraCh1 Timera channel 1
+ ** \arg TimeraCh2 Timera channel 2
+ ** \arg TimeraCh3 Timera channel 3
+ ** \arg TimeraCh4 Timera channel 4
+ ** \arg TimeraCh5 Timera channel 5
+ ** \arg TimeraCh6 Timera channel 6
+ ** \arg TimeraCh7 Timera channel 7
+ ** \arg TimeraCh8 Timera channel 8
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable timera event request
+ ** \arg Enable Enable timera event request
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_EventCmd(M4_TMRA_TypeDef *TIMERAx, en_timera_channel_t enChannel,
+ en_functional_state_t enNewSta)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_NORMAL_TIMERA_CHANNEL(enChannel));
+
+ switch (enChannel)
+ {
+ case TimeraCh1:
+ TIMERAx->ECONR_f.ETEN1 = enNewSta;
+ break;
+ case TimeraCh2:
+ TIMERAx->ECONR_f.ETEN2 = enNewSta;
+ break;
+ case TimeraCh3:
+ TIMERAx->ECONR_f.ETEN3 = enNewSta;
+ break;
+ case TimeraCh4:
+ TIMERAx->ECONR_f.ETEN4 = enNewSta;
+ break;
+ case TimeraCh5:
+ TIMERAx->ECONR_f.ETEN5 = enNewSta;
+ break;
+ case TimeraCh6:
+ TIMERAx->ECONR_f.ETEN6 = enNewSta;
+ break;
+ case TimeraCh7:
+ TIMERAx->ECONR_f.ETEN7 = enNewSta;
+ break;
+ case TimeraCh8:
+ TIMERAx->ECONR_f.ETEN8 = enNewSta;
+ break;
+ default:
+ break;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get Timera flag status
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enFlag Timera flag type
+ ** \arg TimeraFlagCaptureOrCompareCh1 Channel 1 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh2 Channel 2 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh3 Channel 3 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh4 Channel 4 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh5 Channel 5 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh6 Channel 6 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh7 Channel 7 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh8 Channel 8 match flag
+ ** \arg TimeraFlagOverflow Count overflow flag
+ ** \arg TimeraFlagUnderflow Count underflow flag
+ **
+ ** \retval Set Flag is set
+ ** \retval Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t TIMERA_GetFlag(M4_TMRA_TypeDef *TIMERAx, en_timera_flag_type_t enFlag)
+{
+ en_flag_status_t enFlagSta = Reset;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case TimeraFlagCaptureOrCompareCh1:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF1;
+ break;
+ case TimeraFlagCaptureOrCompareCh2:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF2;
+ break;
+ case TimeraFlagCaptureOrCompareCh3:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF3;
+ break;
+ case TimeraFlagCaptureOrCompareCh4:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF4;
+ break;
+ case TimeraFlagCaptureOrCompareCh5:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF5;
+ break;
+ case TimeraFlagCaptureOrCompareCh6:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF6;
+ break;
+ case TimeraFlagCaptureOrCompareCh7:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF7;
+ break;
+ case TimeraFlagCaptureOrCompareCh8:
+ enFlagSta = (en_flag_status_t)TIMERAx->STFLR_f.CMPF8;
+ break;
+ case TimeraFlagOverflow:
+ enFlagSta = (en_flag_status_t)TIMERAx->BCSTR_f.OVFF;
+ break;
+ case TimeraFlagUnderflow:
+ enFlagSta = (en_flag_status_t)TIMERAx->BCSTR_f.UDFF;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return enFlagSta;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear Timera flag status
+ **
+ ** \param [in] TIMERAx Pointer to timera unit configuration address
+ ** \arg M4_TMRA1 Timera unit 1 configuration Address
+ ** \arg M4_TMRA2 Timera unit 2 configuration Address
+ ** \arg M4_TMRA3 Timera unit 3 configuration Address
+ ** \arg M4_TMRA4 Timera unit 4 configuration Address
+ ** \arg M4_TMRA5 Timera unit 5 configuration Address
+ ** \arg M4_TMRA6 Timera unit 6 configuration Address
+ **
+ ** \param [in] enFlag Timera flag type
+ ** \arg TimeraFlagCaptureOrCompareCh1 Channel 1 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh2 Channel 2 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh3 Channel 3 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh4 Channel 4 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh5 Channel 5 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh6 Channel 6 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh7 Channel 7 match flag
+ ** \arg TimeraFlagCaptureOrCompareCh8 Channel 8 match flag
+ ** \arg TimeraFlagOverflow Count overflow flag
+ ** \arg TimeraFlagUnderflow Count underflow flag
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - TIMERAx is invalid
+ **
+ ******************************************************************************/
+en_result_t TIMERA_ClearFlag(M4_TMRA_TypeDef *TIMERAx, en_timera_flag_type_t enFlag)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check parameters */
+ if(IS_VALID_NORMAL_TIMERA_UNIT(TIMERAx))
+ {
+ DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case TimeraFlagCaptureOrCompareCh1:
+ TIMERAx->STFLR_f.CMPF1 = 0u;
+ break;
+ case TimeraFlagCaptureOrCompareCh2:
+ TIMERAx->STFLR_f.CMPF2 = 0u;
+ break;
+ case TimeraFlagCaptureOrCompareCh3:
+ TIMERAx->STFLR_f.CMPF3 = 0u;
+ break;
+ case TimeraFlagCaptureOrCompareCh4:
+ TIMERAx->STFLR_f.CMPF4 = 0u;
+ break;
+ case TimeraFlagCaptureOrCompareCh5:
+ TIMERAx->STFLR_f.CMPF5 = 0u;
+ break;
+ case TimeraFlagCaptureOrCompareCh6:
+ TIMERAx->STFLR_f.CMPF6 = 0u;
+ break;
+ case TimeraFlagCaptureOrCompareCh7:
+ TIMERAx->STFLR_f.CMPF7 = 0u;
+ break;
+ case TimeraFlagCaptureOrCompareCh8:
+ TIMERAx->STFLR_f.CMPF8 = 0u;
+ break;
+ case TimeraFlagOverflow:
+ TIMERAx->BCSTR_f.OVFF = 0u;
+ break;
+ case TimeraFlagUnderflow:
+ TIMERAx->BCSTR_f.UDFF = 0u;
+ break;
+ default:
+ break;
+ }
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set counter event trigger source
+ **
+ ** \param [in] enTriggerSrc Counter event trigger source
+ ** \arg 0-511 Used to trigger counter start/stop/clear/increment/decrement
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SetCountTriggerSrc(en_event_src_t enTriggerSrc)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EVENT_SOURCE(enTriggerSrc));
+
+ M4_AOS->TMRA_HTSSR0_f.TRGSEL = enTriggerSrc;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set capture event trigger source
+ **
+ ** \param [in] enTriggerSrc Capture event trigger source
+ ** \arg 0-511 Used to trigger the capture function
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t TIMERA_SetCaptureTriggerSrc(en_event_src_t enTriggerSrc)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_EVENT_SOURCE(enTriggerSrc));
+
+ M4_AOS->TMRA_HTSSR1_f.TRGSEL = enTriggerSrc;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable TimerA counter common trigger.
+ **
+ ** \param [in] enComTrigger TimerA common trigger selection.
+ ** \arg TimeraComTrigger_1 Select common trigger 1
+ ** \arg TimeraComTrigger_2 Select common trigger 2
+ ** \arg TimeraComTrigger_1_2 Select common trigger 1 and 2
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable the specified common trigger.
+ ** \arg Enable Enable the specified common trigger.
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t TIMERA_CountComTriggerCmd(en_timera_com_trigger_t enComTrigger, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32ComTrig;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ u32ComTrig = (uint32_t)enComTrigger << 30u;
+ if (enNewSta == Enable)
+ {
+ M4_AOS->TMRA_HTSSR0 |= u32ComTrig;
+ }
+ else
+ {
+ M4_AOS->TMRA_HTSSR0 &= ~u32ComTrig;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable TimerA capture common trigger.
+ **
+ ** \param [in] enComTrigger TimerA common trigger selection.
+ ** \arg TimeraComTrigger_1 Select common trigger 1
+ ** \arg TimeraComTrigger_2 Select common trigger 2
+ ** \arg TimeraComTrigger_1_2 Select common trigger 1 and 2
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable the specified common trigger.
+ ** \arg Enable Enable the specified common trigger.
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t TIMERA_CaptureComTriggerCmd(en_timera_com_trigger_t enComTrigger, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+ uint32_t u32ComTrig;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_COM_TRIGGER(enComTrigger));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ u32ComTrig = (uint32_t)enComTrigger << 30u;
+ if (enNewSta == Enable)
+ {
+ M4_AOS->TMRA_HTSSR1 |= u32ComTrig;
+ }
+ else
+ {
+ M4_AOS->TMRA_HTSSR1 &= ~u32ComTrig;
+ }
+
+ return enRet;
+}
+
+//@} // TimeraGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_trng.c b/lib/hc32f460/driver/src/hc32f460_trng.c new file mode 100644 index 00000000..d06a651e --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_trng.c @@ -0,0 +1,260 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_trng.c
+ **
+ ** A detailed description is available at
+ ** @link TrngGroup Trng description @endlink
+ **
+ ** - 2018-10-20 CDT First version for Device Driver Library of Trng.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_trng.h"
+#include "hc32f460_utility.h"
+#include <system_hc32f460.h>
+
+/**
+ *******************************************************************************
+ ** \addtogroup TrngGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*! Parameter validity check for TRNG load control. */
+#define IS_TRNG_LOAD_CTRL(CTRL) \
+( ((CTRL) == TrngLoadNewInitValue_Enable) || \
+ ((CTRL) == TrngLoadNewInitValue_Disable))
+
+/*! Parameter validity check for TRNG shift count. */
+#define IS_TRNG_SHIFT_COUNT(COUNT) \
+( ((COUNT) == TrngShiftCount_32) || \
+ ((COUNT) == TrngShiftCount_64) || \
+ ((COUNT) == TrngShiftCount_128) || \
+ ((COUNT) == TrngShiftCount_256))
+
+
+#define RANDOM_NUM_LENGTH (2u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initializes the TRNG.
+ **
+ ** \param [in] pstcInit Pointer to TRNG initialization structure.
+ ** \arg enLoadCtrl
+ ** \- TrngLoadNewInitValue_Enable Data register load new initial value before
+ ** random number is generated.
+ ** \- TrngLoadNewInitValue_Disable Data register do not load new initial value
+ ** before random number is generated.
+ **
+ ** \arg enShiftCount Shift count control bit when capturing random noise.
+ ** \- TrngShiftCount_32 Shift 32 times.
+ ** \- TrngShiftCount_64 Shift 64 times.
+ ** \- TrngShiftCount_128 Shift 128 times.
+ ** \- TrngShiftCount_256 Shift 256 times.
+ **
+ ** \retval Ok No error occurred.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t TRNG_Init(const stc_trng_init_t *pstcInit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (NULL != pstcInit)
+ {
+ /* Parameter validity check */
+ DDL_ASSERT(IS_TRNG_LOAD_CTRL(pstcInit->enLoadCtrl));
+ DDL_ASSERT(IS_TRNG_SHIFT_COUNT(pstcInit->enShiftCount));
+
+ /* Stop TRNG generating*/
+ bM4_TRNG_CR_RUN = 0u;
+
+ /* Turn off TRNG circuit */
+ bM4_TRNG_CR_EN = 0u;
+
+ M4_TRNG->MR_f.LOAD = pstcInit->enLoadCtrl;
+ M4_TRNG->MR_f.CNT = pstcInit->enShiftCount;
+
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Deinitializes the TRNG.
+ **
+ ** \param None.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void TRNG_DeInit(void)
+{
+ /* Stop TRNG generating*/
+ bM4_TRNG_CR_RUN = 0u;
+
+ /* Turn off TRNG circuit */
+ bM4_TRNG_CR_EN = 0u;
+
+ /* Set the value of all registers to the reset value. */
+ M4_TRNG->CR = 0u;
+ M4_TRNG->MR = 0x12ul;
+ M4_TRNG->DR0 = 0x08000000ul;
+ M4_TRNG->DR0 = 0x08000200ul;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Start TRNG and generate random number.
+ **
+ ** \param [out] pu32Random The destination address where the random
+ ** number will be stored.
+ ** \param [in] u8Length Random number length(in word).
+ ** TRNG generates two random numbers(2 words) at one time.
+ ** u8Length >= 2, both random numbers will be read.
+ ** u8Length < 2, only one random number will be read.
+ ** \param [in] u32Timeout Timeout value.
+ **
+ ** \retval Ok No error occurred.
+ ** \retval ErrorTimeout TRNG works timeout.
+ ** \retval ErrorInvalidParameter Parameter error.
+ **
+ ******************************************************************************/
+en_result_t TRNG_Generate(uint32_t *pu32Random, uint8_t u8Length, uint32_t u32Timeout)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+ uint32_t u32TrngTimeout;
+ __IO uint32_t u32TimeCount;
+
+ if ((NULL != pu32Random) && (0u != u32Timeout) && (0u != u8Length))
+ {
+ /* 10 is the number of required instructions cycles for the below loop statement. */
+ u32TrngTimeout = u32Timeout * (SystemCoreClock / 10u / 1000u);
+
+ /* Turn on TRNG circuit. */
+ bM4_TRNG_CR_EN = 1u;
+
+ /* Start TRNG to generate random number. */
+ bM4_TRNG_CR_RUN = 1u;
+
+ /* wait generation done and check if timeout. */
+ u32TimeCount = 0u;
+ enRet = ErrorTimeout;
+ while (u32TimeCount < u32TrngTimeout)
+ {
+ if (bM4_TRNG_CR_RUN == 0u)
+ {
+ enRet = Ok;
+ break;
+ }
+ u32TimeCount++;
+ }
+
+ if (Ok == enRet)
+ {
+ /* read the random number. */
+ pu32Random[0u] = M4_TRNG->DR0;
+ if (u8Length >= RANDOM_NUM_LENGTH)
+ {
+ pu32Random[1u] = M4_TRNG->DR1;
+ }
+ }
+
+ /* Stop TRNG generating. */
+ bM4_TRNG_CR_RUN = 0u;
+
+ /* Turn off TRNG circuit. */
+ bM4_TRNG_CR_EN = 0u;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Start TRNG only.
+ **
+ ** \param None.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void TRNG_StartIT(void)
+{
+ /* Turn on TRNG circuit. */
+ bM4_TRNG_CR_EN = 1u;
+
+ /* Start TRNG to generate random number. */
+ bM4_TRNG_CR_RUN = 1u;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get random number.
+ **
+ ** \param [out] pu32Random The destination address where the random
+ ** number will be stored.
+ ** \param [in] u8Length Random number length(in word).
+ ** TRNG generates two random numbers(2 words) at one time.
+ ** u8Length >= 2, both random numbers will be read.
+ ** u8Length < 2, only one random number will be read.
+ **
+ ** \retval None.
+ **
+ ******************************************************************************/
+void TRNG_GetRandomNum(uint32_t *pu32Random, uint8_t u8Length)
+{
+ if ((NULL != pu32Random) && (0u != u8Length))
+ {
+ pu32Random[0u] = M4_TRNG->DR0;
+ if (u8Length >= RANDOM_NUM_LENGTH)
+ {
+ pu32Random[1u] = M4_TRNG->DR1;
+ }
+
+ /* Stop TRNG generating */
+ bM4_TRNG_CR_RUN = 0u;
+
+ /* Turn off TRNG circuit */
+ bM4_TRNG_CR_EN = 0u;
+ }
+}
+
+//@} // TrngGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_usart.c b/lib/hc32f460/driver/src/hc32f460_usart.c new file mode 100644 index 00000000..cd56ab28 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_usart.c @@ -0,0 +1,1636 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_usart.c
+ **
+ ** A detailed description is available at
+ ** @link UsartGroup USART description @endlink
+ **
+ ** - 2018-11-27 CDT First version for Device Driver Library of USART.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_usart.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup UsartGroup
+ ******************************************************************************/
+
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+
+/*!< Parameter valid check for USART Instances. */
+#define IS_VALID_USART(__USARTx__) \
+( (M4_USART1 == (__USARTx__)) || \
+ (M4_USART2 == (__USARTx__)) || \
+ (M4_USART3 == (__USARTx__)) || \
+ (M4_USART4 == (__USARTx__)))
+
+/*!< Parameter valid check for USART clock prescale. */
+#define IS_VALID_USART_CLK_DIV(x) \
+( (UsartClkDiv_1 == (x)) || \
+ (UsartClkDiv_4 == (x)) || \
+ (UsartClkDiv_16 == (x)) || \
+ (UsartClkDiv_64 == (x)))
+
+/*!< Parameter valid check for USART function type. */
+#define IS_VALID_USART_FUNC(x) \
+( (UsartRx == (x)) || \
+ (UsartTx == (x)) || \
+ (UsartCts == (x)) || \
+ (UsartRxInt == (x)) || \
+ (UsartTimeOut == (x)) || \
+ (UsartSmartCard == (x)) || \
+ (UsartSilentMode == (x)) || \
+ (UsartTxEmptyInt == (x)) || \
+ (UsartTimeOutInt == (x)) || \
+ (UsartTxCmpltInt == (x)) || \
+ (UsartParityCheck == (x)) || \
+ (UsartNoiseFilter == (x)) || \
+ (UsartFracBaudrate == (x)) || \
+ (UsartMulProcessor == (x)) || \
+ (UsartTxAndTxEmptyInt == (x)))
+
+/*!< Parameter valid check for USART function type. */
+#define IS_VALID_USART_STATUS(x) \
+( (UsartRxMpb == (x)) || \
+ (UsartTxEmpty == (x)) || \
+ (UsartFrameErr == (x)) || \
+ (UsartRxNoEmpty == (x)) || \
+ (UsartRxTimeOut == (x)) || \
+ (UsartParityErr == (x)) || \
+ (UsartOverrunErr == (x)) || \
+ (UsartTxComplete == (x)))
+
+/*!< Parameter valid check for USART clock mode. */
+#define IS_VALID_USART_CLK_MODE(x) \
+( (UsartExtClk == (x)) || \
+ (UsartIntClkCkOutput == (x)) || \
+ (UsartIntClkCkNoOutput == (x)))
+
+/*!< Parameter valid check for USART stop bit. */
+#define IS_VALID_USART_STOP_BIT(x) \
+( (UsartOneStopBit == (x)) || \
+ (UsartTwoStopBit == (x)))
+
+/*!< Parameter valid check for USART parity bit. */
+#define IS_VALID_USART_PARITY_BIT(x) \
+( (UsartParityOdd == (x)) || \
+ (UsartParityEven == (x)) || \
+ (UsartParityNone == (x)))
+
+/*!< Parameter valid check for USART data length. */
+#define IS_VALID_USART_DATA_LEN(x) \
+( (UsartDataBits8 == (x)) || \
+ (UsartDataBits9 == (x)))
+
+/*!< Parameter valid check for USART data direction. */
+#define IS_VALID_USART_DATA_DIR(x) \
+( (UsartDataLsbFirst == (x)) || \
+ (UsartDataMsbFirst == (x)))
+
+/*!< Parameter valid check for USART sample mode. */
+#define IS_VALID_USART_SAMPLE_MODE(x) \
+( (UsartSampleBit8 == (x)) || \
+ (UsartSampleBit16 == (x)))
+
+/*!< Parameter valid check for USART sample mode. */
+#define IS_VALID_USART_HW_FLOW_MODE(x) \
+( (UsartRtsEnable == (x)) || \
+ (UsartCtsEnable == (x)))
+
+/*!< Parameter valid check for USART detect mode. */
+#define IS_VALID_USART_SB_DETECT_MODE(x) \
+( (UsartStartBitLowLvl == (x)) || \
+ (UsartStartBitFallEdge == (x)))
+
+/*!< Parameter valid check for USART mode. */
+#define IS_VALID_USART_MODE(x) \
+( (UsartUartMode == (x)) || \
+ (UsartClkSyncMode == (x)) || \
+ (UsartSmartCardMode == (x)))
+
+/*!< Parameter valid check for USART ETU clocks number. */
+#define IS_VALID_USART_ETU_CLK(x) \
+( (UsartScEtuClk32 == (x)) || \
+ (UsartScEtuClk64 == (x)) || \
+ (UsartScEtuClk128 == (x)) || \
+ (UsartScEtuClk256 == (x)) || \
+ (UsartScEtuClk372 == (x)))
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+static uint32_t UsartGetClk(const M4_USART_TypeDef *USARTx);
+static en_result_t SetUartBaudrate(M4_USART_TypeDef *USARTx,
+ uint32_t u32Baudrate);
+static en_result_t SetClkSyncBaudrate(M4_USART_TypeDef *USARTx,
+ uint32_t u32Baudrate);
+static en_result_t SetScBaudrate(M4_USART_TypeDef *USARTx,
+ uint32_t u32Baudrate);
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initialize UART mode of the specified USART.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] pstcInitCfg Pointer to USART mode configure structure
+ ** \arg This parameter detail refer @ref stc_usart_uart_init_t
+ **
+ ** \retval Ok USART is initialized normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - USARTx is invalid
+ ** - pstcInitCfg == NULL
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t USART_UART_Init(M4_USART_TypeDef *USARTx,
+ const stc_usart_uart_init_t *pstcInitCfg)
+{
+ stc_usart_pr_field_t PR_f = {0};
+ stc_usart_cr1_field_t CR1_f = {0};
+ stc_usart_cr2_field_t CR2_f = {0};
+ stc_usart_cr3_field_t CR3_f = {0};
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx && pstcInitCfg pointer */
+ if ((IS_VALID_USART(USARTx)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_USART_CLK_DIV(pstcInitCfg->enClkDiv));
+ DDL_ASSERT(IS_VALID_USART_CLK_MODE(pstcInitCfg->enClkMode));
+ DDL_ASSERT(IS_VALID_USART_STOP_BIT(pstcInitCfg->enStopBit));
+ DDL_ASSERT(IS_VALID_USART_PARITY_BIT(pstcInitCfg->enParity));
+ DDL_ASSERT(IS_VALID_USART_DATA_DIR(pstcInitCfg->enDirection));
+ DDL_ASSERT(IS_VALID_USART_DATA_LEN(pstcInitCfg->enDataLength));
+ DDL_ASSERT(IS_VALID_USART_HW_FLOW_MODE(pstcInitCfg->enHwFlow));
+ DDL_ASSERT(IS_VALID_USART_SAMPLE_MODE(pstcInitCfg->enSampleMode));
+ DDL_ASSERT(IS_VALID_USART_SB_DETECT_MODE(pstcInitCfg->enDetectMode));
+
+ /* Set default value */
+ USARTx->CR1 = (uint32_t)0x801B0000ul;
+ USARTx->CR2 = (uint32_t)0x00000000ul;
+ USARTx->CR3 = (uint32_t)0x00000000ul;
+ USARTx->BRR = (uint32_t)0x0000FFFFul;
+ USARTx->PR = (uint32_t)0x00000000ul;
+
+ /* Set USART mode */
+ CR3_f.SCEN = (uint32_t)0ul;
+ CR1_f.MS = (uint32_t)0ul;
+
+ PR_f.PSC = (uint32_t)(pstcInitCfg->enClkDiv);
+ CR1_f.M = (uint32_t)(pstcInitCfg->enDataLength);
+ CR1_f.ML = (uint32_t)(pstcInitCfg->enDirection);
+ CR2_f.STOP = (uint32_t)(pstcInitCfg->enStopBit);
+ CR2_f.CLKC = (uint32_t)(pstcInitCfg->enClkMode);
+
+ switch(pstcInitCfg->enParity)
+ {
+ case UsartParityNone:
+ CR1_f.PCE = (uint32_t)0ul;
+ break;
+ case UsartParityEven:
+ CR1_f.PS = (uint32_t)0ul;
+ CR1_f.PCE = (uint32_t)1ul;
+ break;
+ case UsartParityOdd:
+ CR1_f.PS = (uint32_t)1ul;
+ CR1_f.PCE = (uint32_t)1ul;
+ break;
+ default:
+ break;
+ }
+
+ CR3_f.CTSE = (uint32_t)(pstcInitCfg->enHwFlow);
+ CR1_f.SBS = (uint32_t)(pstcInitCfg->enDetectMode);
+ CR1_f.OVER8 = (uint32_t)(pstcInitCfg->enSampleMode);
+
+ USARTx->PR_f = PR_f;
+ USARTx->CR2_f= CR2_f;
+ USARTx->CR3_f= CR3_f;
+ USARTx->CR1_f= CR1_f;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+/**
+ *******************************************************************************
+ ** \brief Initialize clock sync mode of the specified USART.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] pstcInitCfg Pointer to clock sync mode configure structure
+ ** \arg This parameter detail refer @ref stc_usart_clksync_init_t
+ **
+ ** \retval Ok USART is initialized normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - USARTx is invalid
+ ** - pstcInitCfg == NULL
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t USART_CLKSYNC_Init(M4_USART_TypeDef *USARTx,
+ const stc_usart_clksync_init_t *pstcInitCfg)
+{
+ stc_usart_pr_field_t PR_f = {0};
+ stc_usart_cr1_field_t CR1_f = {0};
+ stc_usart_cr2_field_t CR2_f = {0};
+ stc_usart_cr3_field_t CR3_f = {0};
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx && pstcInitCfg pointer */
+ if ((IS_VALID_USART(USARTx)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_USART_CLK_DIV(pstcInitCfg->enClkDiv));
+ DDL_ASSERT(IS_VALID_USART_CLK_MODE(pstcInitCfg->enClkMode));
+ DDL_ASSERT(IS_VALID_USART_DATA_DIR(pstcInitCfg->enDirection));
+ DDL_ASSERT(IS_VALID_USART_HW_FLOW_MODE(pstcInitCfg->enHwFlow));
+
+ /* Set default value */
+ USARTx->CR1 = (uint32_t)0x801B0000ul;
+ USARTx->CR2 = (uint32_t)0x00000000ul;
+ USARTx->CR3 = (uint32_t)0x00000000ul;
+ USARTx->BRR = (uint32_t)0x0000FFFFul;
+ USARTx->PR = (uint32_t)0x00000000ul;
+
+ /* Set Clock Sync mode */
+ CR3_f.SCEN = (uint32_t)0ul;
+ CR1_f.MS = (uint32_t)1ul;
+ CR1_f.ML = (uint32_t)(pstcInitCfg->enDirection);
+ PR_f.PSC = (uint32_t)(pstcInitCfg->enClkDiv);
+ CR2_f.CLKC = (uint32_t)(pstcInitCfg->enClkMode);
+ CR3_f.CTSE = (uint32_t)(pstcInitCfg->enHwFlow);
+
+ USARTx->PR_f = PR_f;
+ USARTx->CR2_f= CR2_f;
+ USARTx->CR3_f= CR3_f;
+ USARTx->CR1_f= CR1_f;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize smart card mode of the specified USART.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] pstcInitCfg Pointer to smart card mode configure structure
+ ** \arg This parameter detail refer @ref stc_usart_sc_init_t
+ **
+ ** \retval Ok USART is initialized normally
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - USARTx is invalid
+ ** - pstcInitCfg == NULL
+ ** - Other invalid configuration
+ **
+ ******************************************************************************/
+en_result_t USART_SC_Init(M4_USART_TypeDef *USARTx,
+ const stc_usart_sc_init_t *pstcInitCfg)
+{
+ stc_usart_pr_field_t PR_f = {0};
+ stc_usart_cr1_field_t CR1_f = {0};
+ stc_usart_cr2_field_t CR2_f = {0};
+ stc_usart_cr3_field_t CR3_f = {0};
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx && pstcInitCfg pointer */
+ if ((IS_VALID_USART(USARTx)) && (NULL != pstcInitCfg))
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_USART_CLK_DIV(pstcInitCfg->enClkDiv));
+ DDL_ASSERT(IS_VALID_USART_CLK_MODE(pstcInitCfg->enClkMode));
+ DDL_ASSERT(IS_VALID_USART_DATA_DIR(pstcInitCfg->enDirection));
+
+ /* Set default value */
+ USARTx->CR1 = (uint32_t)0x801B0000ul;
+ USARTx->CR2 = (uint32_t)0x00000000ul;
+ USARTx->CR3 = (uint32_t)0x00000000ul;
+ USARTx->BRR = (uint32_t)0x0000FFFFul;
+ USARTx->PR = (uint32_t)0x00000000ul;
+
+ CR1_f.PCE = (uint32_t)1ul;
+ CR1_f.ML = (uint32_t)(pstcInitCfg->enDirection);
+ CR2_f.CLKC = (uint32_t)(pstcInitCfg->enClkMode);
+ CR3_f.SCEN = (uint32_t)1ul; /* Set USART mode */
+ CR3_f.BCN = (uint32_t)UsartScEtuClk372; /* ETU = 372 * CK */
+ PR_f.PSC = (uint32_t)(pstcInitCfg->enClkDiv);
+
+ USARTx->PR_f = PR_f;
+ USARTx->CR2_f= CR2_f;
+ USARTx->CR3_f= CR3_f;
+ USARTx->CR1_f= CR1_f;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief De-Initializes the specified USART.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval Ok USART is de-initialized normally
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_DeInit(M4_USART_TypeDef *USARTx)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check for USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ /* Set default value */
+ USARTx->CR1 = (uint32_t)0x801B0000ul;
+ USARTx->CR2 = (uint32_t)0x00000000ul;
+ USARTx->CR3 = (uint32_t)0x00000000ul;
+ USARTx->BRR = (uint32_t)0x0000FFFFul;
+ USARTx->PR = (uint32_t)0x00000000ul;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get flag status
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enStatus Choose need get status's flag
+ ** \arg UsartParityError Parity check error
+ ** \arg UsartFrameError Frame error
+ ** \arg UsartOverRunError Overrun error
+ ** \arg UsartRxRegNoEmpty Rx register is no empty
+ ** \arg UsartTxComplete Transfer completely
+ ** \arg UsartTxRegNoEmpty Tx register is no empty
+ ** \arg UsartRxTimeOut Data receive timeout
+ ** \arg UsartRxDataType Data is multiple processor id or normal data.
+ **
+ ** \retval Set Flag is set.
+ ** \retval Reset Flag is reset or enStatus is invalid.
+ **
+ ******************************************************************************/
+en_flag_status_t USART_GetStatus(M4_USART_TypeDef *USARTx,
+ en_usart_status_t enStatus)
+{
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+ DDL_ASSERT(IS_VALID_USART_STATUS(enStatus));
+
+ return ((USARTx->SR & enStatus) ? Set : Reset);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear the specified USART status
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enStatus The specified status
+ ** \arg UsartParityErr Parity check error
+ ** \arg UsartFrameErr Frame error
+ ** \arg UsartOverRunErr Overrun error
+ ** \arg UsartRxTimeOut Data receive timeout
+ **
+ ** \retval Ok Clear flag successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - USARTx is invalid
+ ** - enStatus is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_ClearStatus(M4_USART_TypeDef *USARTx,
+ en_usart_status_t enStatus)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ enRet = Ok;
+ switch (enStatus)
+ {
+ case UsartParityErr:
+ USARTx->CR1_f.CPE = 1ul;
+ break;
+ case UsartFrameErr:
+ USARTx->CR1_f.CFE = 1ul;
+ break;
+ case UsartOverrunErr:
+ USARTx->CR1_f.CORE = 1ul;
+ break;
+ case UsartRxTimeOut:
+ USARTx->CR1_f.CRTOF = 1ul;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Configure USART function.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enFunc USART function selection
+ ** \arg UsartTimeOut UART RX timeout function
+ ** \arg UsartTimeOutInt UART RX timeout interrupt function
+ ** \arg UsartRx UART RX function
+ ** \arg UsartTx UART TX function
+ ** \arg UsartSilentMode USART silent function
+ ** \arg UsartRxInt USART RX interrupt function
+ ** \arg UsartTxCmpltInt USART TX complete interrupt function
+ ** \arg UsartTxEmptyInt USART TX empty interrupt function
+ ** \arg UsartParityCheck USART Parity check function
+ ** \arg UsartFracBaudrate USART fractional baudrate function
+ ** \arg UsartNoiseFilter USART noise filter function
+ ** \param [in] enCmd USART functional state
+ ** \arg Enable Enable the specified USART function
+ ** \arg Disable Disable the specified USART function
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - USARTx == NULL
+ **
+ ******************************************************************************/
+en_result_t USART_FuncCmd(M4_USART_TypeDef *USARTx,
+ en_usart_func_t enFunc,
+ en_functional_state_t enCmd)
+{
+ uint32_t u32Addr;
+ __IO stc_usart_cr1_field_t CR1_f;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ enRet = Ok;
+ switch(enFunc)
+ {
+ case UsartRx:
+ USARTx->CR1_f.RE = (uint32_t)enCmd;
+ break;
+ case UsartRxInt:
+ USARTx->CR1_f.RIE = (uint32_t)enCmd;
+ break;
+ case UsartTx:
+ USARTx->CR1_f.TE = (uint32_t)enCmd;
+ break;
+ case UsartTxEmptyInt:
+ USARTx->CR1_f.TXEIE = (uint32_t)enCmd;
+ break;
+ case UsartTimeOut:
+ USARTx->CR1_f.RTOE = (uint32_t)enCmd;
+ break;
+ case UsartTimeOutInt:
+ USARTx->CR1_f.RTOIE = (uint32_t)enCmd;
+ break;
+ case UsartSilentMode:
+ USARTx->CR1_f.SLME = (uint32_t)enCmd;
+ break;
+ case UsartParityCheck:
+ USARTx->CR1_f.PCE = (uint32_t)enCmd;
+ break;
+ case UsartNoiseFilter:
+ USARTx->CR1_f.NFE = (uint32_t)enCmd;
+ break;
+ case UsartTxCmpltInt:
+ USARTx->CR1_f.TCIE = (uint32_t)enCmd;
+ break;
+ case UsartTxAndTxEmptyInt:
+ CR1_f = USARTx->CR1_f;
+ CR1_f.TE = (uint32_t)enCmd;
+ CR1_f.TXEIE = (uint32_t)enCmd;
+ u32Addr = (uint32_t)&CR1_f;
+ USARTx->CR1 = *(__IO uint32_t *)u32Addr;
+ break;
+ case UsartFracBaudrate:
+ USARTx->CR1_f.FBME = (uint32_t)enCmd;
+ break;
+ case UsartMulProcessor:
+ USARTx->CR2_f.MPE = (uint32_t)enCmd;
+ break;
+ case UsartSmartCard:
+ USARTx->CR3_f.SCEN = (uint32_t)enCmd;
+ break;
+ case UsartCts:
+ USARTx->CR3_f.CTSE = (uint32_t)enCmd;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART parity bit.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enParity USART parity selection
+ ** \arg UsartParityNone USART none parity
+ ** \arg UsartParityEven USART even parity
+ ** \arg UsartParityOdd USART odd parity
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - USARTx is invalid
+ ** - enParity is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetParity(M4_USART_TypeDef *USARTx,
+ en_usart_parity_t enParity)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ enRet = Ok;
+ switch(enParity)
+ {
+ case UsartParityNone:
+ USARTx->CR1_f.PCE = (uint32_t)0ul;
+ break;
+ case UsartParityEven:
+ USARTx->CR1_f.PS = (uint32_t)0ul;
+ USARTx->CR1_f.PCE = (uint32_t)1u;
+ break;
+ case UsartParityOdd:
+ USARTx->CR1_f.PS = (uint32_t)1ul;
+ USARTx->CR1_f.PCE = (uint32_t)1ul;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART parity bit.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartParityNone USART none parity
+ ** \retval UsartParityEven USART even parity
+ ** \retval UsartParityOdd USART odd parity
+ **
+ ******************************************************************************/
+en_usart_parity_t USART_GetParity(M4_USART_TypeDef *USARTx)
+{
+ en_usart_parity_t enParity = UsartParityNone;
+
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ if(0ul == USARTx->CR1_f.PCE)
+ {
+ enParity = UsartParityNone;
+ }
+ else if(0ul == USARTx->CR1_f.PS)
+ {
+ enParity = UsartParityEven;
+ }
+ else
+ {
+ enParity = UsartParityOdd;
+ }
+
+ return enParity;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART over sampling.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enSampleMode USART parity selection
+ ** \arg UsartSampleBit16 16 Bit
+ ** \arg UsartSampleBit8 8 Bit
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetOverSampling(M4_USART_TypeDef *USARTx,
+ en_usart_sample_mode_t enSampleMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_SAMPLE_MODE(enSampleMode));
+
+ USARTx->CR1_f.OVER8 = (uint32_t)enSampleMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART over sampling.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartSampleBit16 16 Bit
+ ** \retval UsartSampleBit8 8 Bit
+ **
+ ******************************************************************************/
+en_usart_sample_mode_t USART_GetOverSampling(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_sample_mode_t)USARTx->CR1_f.OVER8;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART data transfer direction.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enDir USART data direction selection
+ ** \arg UsartDataLsbFirst USART data LSB first
+ ** \arg UsartDataMsbFirst USART data MSB first
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetTransferDirection(M4_USART_TypeDef *USARTx,
+ en_usart_data_dir_t enDir)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_DATA_DIR(enDir));
+
+ USARTx->CR1_f.ML = (uint32_t)enDir;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART data transfer direction.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartDataLsbFirst USART data LSB first
+ ** \retval UsartDataMsbFirst USART data MSB first
+ **
+ ******************************************************************************/
+en_usart_data_dir_t USART_GetTransferDirection(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_data_dir_t)(USARTx->CR1_f.ML);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART data bit length.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enDataLen USART data bit length
+ ** \arg UsartDataBits8 8 Bit
+ ** \arg UsartDataBits8 9 Bit
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetDataLength(M4_USART_TypeDef *USARTx,
+ en_usart_data_len_t enDataLen)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_DATA_LEN(enDataLen));
+
+ USARTx->CR1_f.M = (uint32_t)enDataLen;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART data bit length.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartDataBits8 Data bit length:8 Bits
+ ** \retval UsartDataBits8 Data bit length:9 Bits
+ **
+ ******************************************************************************/
+en_usart_data_len_t USART_GetDataLength(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_data_len_t)(USARTx->CR1_f.M);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART clock mode.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enClkMode USART clock mode selection
+ ** \arg UsartExtClk Select external clock source
+ ** \arg UsartIntClkCkOutput Select internal clock source and output clock
+ ** \arg UsartIntClkCkNoOutput Select internal clock source and don't output clock
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetClkMode(M4_USART_TypeDef *USARTx,
+ en_usart_clk_mode_t enClkMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_CLK_MODE(enClkMode));
+
+ USARTx->CR2_f.CLKC = (uint32_t)enClkMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART clock mode.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartExtClk Select external clock source
+ ** \retval UsartIntClkCkOutput Select internal clock source and output clock
+ ** \retval UsartIntClkCkNoOutput Select internal clock source and don't output clock
+ **
+ ******************************************************************************/
+en_usart_clk_mode_t USART_GetClkMode(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_clk_mode_t)(USARTx->CR2_f.CLKC);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART mode.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enMode USART clock mode selection
+ ** \arg UsartUartMode UART mode
+ ** \arg UsartClkSyncMode Clock sync mode
+ ** \arg UsartSmartCardMode Smart card mode
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter If one of following cases matches:
+ ** - USARTx is invalid
+ ** - enMode is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetMode(M4_USART_TypeDef *USARTx,
+ en_usart_mode_t enMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if(IS_VALID_USART(USARTx))
+ {
+ enRet = Ok;
+ switch(enMode)
+ {
+ case UsartUartMode:
+ USARTx->CR3_f.SCEN = (uint32_t)0ul;
+ USARTx->CR1_f.MS = (uint32_t)0ul;
+ break;
+ case UsartClkSyncMode:
+ USARTx->CR3_f.SCEN = (uint32_t)0ul;
+ USARTx->CR1_f.MS = (uint32_t)1ul;
+ break;
+ case UsartSmartCardMode:
+ USARTx->CR3_f.SCEN = (uint32_t)1ul;
+ break;
+ default:
+ enRet = ErrorInvalidParameter;
+ break;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART mode.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartUartMode UART mode
+ ** \retval UsartClkSyncMode Clock sync mode
+ ** \retval UsartSmartCardMode Smart card mode
+ **
+ ******************************************************************************/
+en_usart_mode_t USART_GetMode(M4_USART_TypeDef *USARTx)
+{
+ en_usart_mode_t enMode;
+
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ if (1ul == USARTx->CR3_f.SCEN)
+ {
+ enMode = UsartSmartCardMode;
+ }
+ else if (1ul == USARTx->CR1_f.MS)
+ {
+ enMode = UsartClkSyncMode;
+ }
+ else
+ {
+ enMode = UsartUartMode;
+ }
+
+ return enMode;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART stop bit length.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enStopBit USART stop bit selection
+ ** \arg UsartOneStopBit 1 Stop Bit
+ ** \arg UsartTwoStopBits 2 Stop Bit
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetStopBitsLength(M4_USART_TypeDef *USARTx,
+ en_usart_stop_bit_t enStopBit)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_STOP_BIT(enStopBit));
+
+ USARTx->CR2_f.STOP = (uint32_t)enStopBit;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART stop bit length.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartOneStopBit 1 Stop Bit
+ ** \retval UsartTwoStopBits 2 Stop Bit
+ **
+ ******************************************************************************/
+en_usart_stop_bit_t USART_GetStopBitsLength(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_stop_bit_t)(USARTx->CR2_f.STOP);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART detect mode.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enDetectMode USART start bit detect mode
+ ** \arg UsartStartBitLowLvl Start bit: RD pin low level
+ ** \arg UsartStartBitFallEdge Start bit: RD pin falling edge
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetSbDetectMode(M4_USART_TypeDef *USARTx,
+ en_usart_sb_detect_mode_t enDetectMode)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_SB_DETECT_MODE(enDetectMode));
+
+ USARTx->CR1_f.SBS = (uint32_t)enDetectMode;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART detect mode.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartStartBitLowLvl Start bit: RD pin low level
+ ** \retval UsartStartBitFallEdge Start bit: RD pin falling edge
+ **
+ ******************************************************************************/
+en_usart_sb_detect_mode_t USART_GetSbDetectMode(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_sb_detect_mode_t)(USARTx->CR1_f.SBS);
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Set USART hardware flow control.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enHwFlowCtrl Hardware flow control
+ ** \arg UsartRtsEnable Enable RTS
+ ** \arg UsartCtsEnable Enable CTS
+ **
+ ** \retval Ok Set successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetHwFlowCtrl(M4_USART_TypeDef *USARTx,
+ en_usart_hw_flow_ctrl_t enHwFlowCtrl)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_HW_FLOW_MODE(enHwFlowCtrl));
+
+ USARTx->CR3_f.CTSE = (uint32_t)enHwFlowCtrl;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART hardware flow control.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartRtsEnable Enable RTS
+ ** \retval UsartCtsEnable Enable CTS
+ **
+ ******************************************************************************/
+en_usart_hw_flow_ctrl_t USART_GetHwFlowCtrl(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_hw_flow_ctrl_t)(USARTx->CR3_f.CTSE);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART clock prescale.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enClkPrescale USART clock prescale
+ ** \arg UsartClkDiv_0 PCLK/1
+ ** \arg UsartClkDiv_4 PCLK/4
+ ** \arg UsartClkDiv_16 PCLK/16
+ ** \arg UsartClkDiv_64 PCLK/64
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetClockDiv(M4_USART_TypeDef *USARTx,
+ en_usart_clk_div_t enClkPrescale)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_CLK_DIV(enClkPrescale));
+
+ USARTx->PR_f.PSC = (uint32_t)enClkPrescale;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART clock division.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartClkDiv_0 PCLK/1
+ ** \retval UsartClkDiv_4 PCLK/4
+ ** \retval UsartClkDiv_16 PCLK/16
+ ** \retval UsartClkDiv_64 PCLK/64
+ **
+ ******************************************************************************/
+en_usart_clk_div_t USART_GetClockDiv(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_clk_div_t)(USARTx->PR_f.PSC);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART ETU clocks of smart card.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] enEtuClk ETU clocks of smart card
+ ** \arg UsartScEtuClk32 1 etu = 32/f
+ ** \arg UsartScEtuClk64 1 etu = 64/f
+ ** \arg UsartScEtuClk93 1 etu = 93/f
+ ** \arg UsartScEtuClk128 1 etu = 128/f
+ ** \arg UsartScEtuClk186 1 etu = 186/f
+ ** \arg UsartScEtuClk256 1 etu = 256/f
+ ** \arg UsartScEtuClk372 1 etu = 372/f
+ ** \arg UsartScEtuClk512 1 etu = 512/f
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetScEtuClk(M4_USART_TypeDef *USARTx,
+ en_usart_sc_etu_clk_t enEtuClk)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ /* Check parameter */
+ DDL_ASSERT(IS_VALID_USART_ETU_CLK(enEtuClk));
+
+ USARTx->CR3_f.BCN = (uint32_t)enEtuClk;
+ enRet = Ok;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART ETU clocks of smart card.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval UsartScEtuClk32 1 etu = 32/f
+ ** \retval UsartScEtuClk64 1 etu = 64/f
+ ** \retval UsartScEtuClk93 1 etu = 93/f
+ ** \retval UsartScEtuClk128 1 etu = 128/f
+ ** \retval UsartScEtuClk186 1 etu = 186/f
+ ** \retval UsartScEtuClk256 1 etu = 256/f
+ ** \retval UsartScEtuClk372 1 etu = 372/f
+ ** \retval UsartScEtuClk512 1 etu = 512/f
+ **
+ ******************************************************************************/
+en_usart_sc_etu_clk_t USART_GetScEtuClk(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return (en_usart_sc_etu_clk_t)(USARTx->CR3_f.BCN);
+}
+
+/**
+ ******************************************************************************
+ ** \brief Write UART data buffer
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] u16Data Send data
+ **
+ ** \retval Ok Data has been successfully sent
+ **
+ ******************************************************************************/
+en_result_t USART_SendData(M4_USART_TypeDef *USARTx, uint16_t u16Data)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ USARTx->DR_f.TDR = (uint32_t)u16Data;
+
+ return Ok;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Read UART data buffer
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval Receive data
+ **
+ ******************************************************************************/
+uint16_t USART_RecData(M4_USART_TypeDef *USARTx)
+{
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ return ((uint16_t)(USARTx->DR_f.RDR));
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set USART baudrate
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] u32Baudrate Baudrate
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+en_result_t USART_SetBaudrate(M4_USART_TypeDef *USARTx,
+ uint32_t u32Baudrate)
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ if(1ul == USARTx->CR3_f.SCEN)
+ {
+ enRet = SetScBaudrate(USARTx, u32Baudrate);
+ }
+ else if(1ul == USARTx->CR1_f.MS)
+ {
+ enRet = SetClkSyncBaudrate(USARTx, u32Baudrate);
+ }
+ else
+ {
+ enRet = SetUartBaudrate(USARTx, u32Baudrate);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set UART mode baudrate
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] u32Baudrate Baudrate
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+static en_result_t SetUartBaudrate(M4_USART_TypeDef *USARTx,
+ uint32_t u32Baudrate)
+{
+ uint32_t B = 0ul;
+ uint32_t C = 0ul;
+ uint32_t OVER8 = 0ul;
+ float32_t DIV = 0.0f;
+ uint64_t u64Tmp = 0u;
+ uint32_t DIV_Integer = 0ul;
+ uint32_t DIV_Fraction = 0xFFFFFFFFul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ C = UsartGetClk(USARTx);
+
+ if (C > 0ul)
+ {
+ B = u32Baudrate;
+ OVER8 = USARTx->CR1_f.OVER8;
+ /* FBME = 0 Calculation formula */
+ /* B = C / (8 * (2 - OVER8) * (DIV_Integer + 1)) */
+ /* DIV_Integer = (C / (B * 8 * (2 - OVER8))) - 1 */
+ DIV = ((float)C / ((float)B * 8.0f * (2.0f - (float)OVER8))) - 1.0f;
+ DIV_Integer = (uint32_t)(DIV);
+
+ if (!((DIV < 0.0f) || (DIV_Integer > 0xFFul)))
+ {
+ enRet = Ok;
+ if ((DIV - (float32_t)DIV_Integer) > 0.00001f)
+ {
+ /* FBME = 1 Calculation formula */
+ /* B = C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256) */
+ /* DIV_Fraction = ((8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B) / C) - 128 */
+ /* E = (C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B)) - 1 */
+ /* DIV_Fraction = (((2 - OVER8) * (DIV_Integer + 1) * 2048 * B) / C) - 128 */
+ u64Tmp = (uint64_t)(((uint64_t)2ul - (uint64_t)OVER8) * ((uint64_t)DIV_Integer + 1ul) * (uint64_t)B);
+ DIV_Fraction = (uint32_t)(2048ul * u64Tmp / C - 128ul);
+ if (DIV_Fraction > 0x7Ful)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ if (Ok == enRet)
+ {
+ USARTx->CR1_f.FBME = (DIV_Fraction > 0x7Ful) ? 0ul : 1ul;
+ USARTx->BRR_f.DIV_FRACTION = DIV_Fraction;
+ USARTx->BRR_f.DIV_INTEGER = DIV_Integer;
+ }
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set smart card mode baudrate
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] u32Baudrate Baudrate
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+static en_result_t SetScBaudrate(M4_USART_TypeDef *USARTx,
+ uint32_t u32Baudrate)
+{
+ uint32_t B = 0ul;
+ uint32_t C = 0ul;
+ uint32_t S = 0ul;
+ float32_t DIV = 0.0f;
+ uint64_t u64Tmp = 0u;
+ uint32_t DIV_Integer = 0ul;
+ uint32_t DIV_Fraction = 0xFFFFFFFFul;
+ const uint16_t au16EtuClkCnts[] = {32u, 64u, 93u, 128u, 186u, 256u, 372u, 512u};
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ C = UsartGetClk(USARTx);
+
+ if (C > 0ul)
+ {
+ B = u32Baudrate;
+ S = au16EtuClkCnts[USARTx->CR3_f.BCN];
+
+ /* FBME = 0 Calculation formula */
+ /* B = C / (2 * S * (DIV_Integer + 1)) */
+ /* DIV_Integer = (C / (B * 2 * S)) - 1 */
+ DIV = ((float)C / ((float)B * (float)S * 2.0f)) - 1.0f;
+ DIV_Integer = (uint32_t)DIV;
+
+ if (!((DIV < 0.0f) || (DIV_Integer > 0xFFul)))
+ {
+ enRet = Ok;
+ if ((DIV - (float32_t)DIV_Integer) > 0.00001f)
+ {
+ /* FBME = 1 Calculation formula */
+ /* B = C * (128 + DIV_Fraction) / ((2 * S) * (DIV_Integer + 1) * 256) */
+ /* DIV_Fraction = ((2 * S) * (DIV_Integer + 1) * 256 * B / C) - 128 */
+ /* DIV_Fraction = ((DIV_Integer + 1) * B * S * 512 / C) - 128 */
+ u64Tmp = (uint64_t)(((uint64_t)DIV_Integer + 1ul) * B * S);
+ DIV_Fraction = (uint32_t)(512ul * u64Tmp / C - 128ul);
+ if (DIV_Fraction > 0x7Ful)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ if (Ok == enRet)
+ {
+ USARTx->CR1_f.FBME = (DIV_Fraction > 0x7Ful) ? 0ul : 1ul;
+ USARTx->BRR_f.DIV_FRACTION = DIV_Fraction;
+ USARTx->BRR_f.DIV_INTEGER = DIV_Integer;
+ }
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set synchronous clock mode baudrate
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ ** \param [in] u32Baudrate Baudrate
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+static en_result_t SetClkSyncBaudrate(M4_USART_TypeDef *USARTx,
+ uint32_t u32Baudrate)
+{
+ uint32_t C = 0ul;
+ uint32_t B = 0ul;
+ uint64_t u64Tmp = 0u;
+ float32_t DIV = 0.0f;
+ uint32_t DIV_Integer = 0ul;
+ uint32_t DIV_Fraction = 0xFFFFFFFFul;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ /* Check USARTx pointer */
+ if (IS_VALID_USART(USARTx))
+ {
+ C = UsartGetClk(USARTx);
+ if (C > 0ul)
+ {
+ B = u32Baudrate;
+
+ /* FBME = 0 Calculation formula */
+ /* B = C / (4 * (DIV_Integer + 1)) */
+ /* DIV_Integer = (C / (B * 4)) - 1 */
+ DIV = ((float)C / ((float)B * 4.0f)) - 1.0f;
+ DIV_Integer = (uint32_t)DIV;
+
+ if (!((DIV < 0.0f) || (DIV_Integer > 0xFFul)))
+ {
+ enRet = Ok;
+ if ((DIV - (float32_t)DIV_Integer) > 0.00001f)
+ {
+ /* FBME = 1 Calculation formula */
+ /* B = C * (128 + DIV_Fraction) / (4 * (DIV_Integer + 1) * 256) */
+ /* DIV_Fraction = (4 * (DIV_Integer + 1) * 256 * B / C) - 128 */
+ /* DIV_Fraction = ((DIV_Integer + 1) * B * 1024 / C) - 128 */
+ u64Tmp = (uint64_t)(((uint64_t)DIV_Integer + 1ul) * (uint64_t)B);
+ DIV_Fraction = (uint32_t)(1024ul * u64Tmp / C - 128ul);
+ if (DIV_Fraction > 0x7Ful)
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ }
+
+ if (Ok == enRet)
+ {
+ USARTx->CR1_f.FBME = (DIV_Fraction > 0x7Ful) ? 0ul : 1ul;
+ USARTx->BRR_f.DIV_FRACTION = DIV_Fraction;
+ USARTx->BRR_f.DIV_INTEGER = DIV_Integer;
+ }
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get USART clock
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** \arg M4_USART1 USART unit 1 instance register base
+ ** \arg M4_USART2 USART unit 2 instance register base
+ ** \arg M4_USART3 USART unit 3 instance register base
+ ** \arg M4_USART4 USART unit 4 instance register base
+ **
+ ** \retval USART clock frequency
+ **
+ ******************************************************************************/
+static uint32_t UsartGetClk(const M4_USART_TypeDef *USARTx)
+{
+ uint32_t u32PClk1 = 0ul;
+ uint32_t u32UartClk = 0ul;
+
+ /* Check USARTx pointer */
+ DDL_ASSERT(IS_VALID_USART(USARTx));
+
+ u32PClk1 = SystemCoreClock / (1ul << M4_SYSREG->CMU_SCFGR_f.PCLK1S);
+ u32UartClk = u32PClk1 / (1ul << (2ul * USARTx->PR_f.PSC));
+
+ return u32UartClk;
+}
+
+//@} // UsartGroup
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_utility.c b/lib/hc32f460/driver/src/hc32f460_utility.c new file mode 100644 index 00000000..87d82d39 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_utility.c @@ -0,0 +1,526 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_utility.c
+ **
+ ** A detailed description is available at
+ ** @link DdlUtilityGroup Ddl Utility description @endlink
+ **
+ ** - 2018-11-02 CDT First version for Device Driver Library Utility.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_utility.h"
+
+#if defined(DDL_UTILITY_ENABLE)
+asdf
+/**
+ *******************************************************************************
+ ** \addtogroup DdlUtilityGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+#if defined(PRINT_ENABLE)
+/*!< Parameter valid check for USART Instances. */
+#define IS_VALID_UART(x) \
+( (M4_USART1 == (x)) || \
+ (M4_USART2 == (x)) || \
+ (M4_USART3 == (x)) || \
+ (M4_USART4 == (x)))
+
+#define UART_EnableClk(x) \
+do { \
+ if (M4_USART1 == (x)) \
+ { \
+ M4_MSTP->FCG1_f.USART1 = 0ul; \
+ } \
+ else if (M4_USART2 == (x)) \
+ { \
+ M4_MSTP->FCG1_f.USART2 = 0ul; \
+ } \
+ else if (M4_USART3 == (x)) \
+ { \
+ M4_MSTP->FCG1_f.USART3 = 0ul; \
+ } \
+ else \
+ { \
+ M4_MSTP->FCG1_f.USART4 = 0ul; \
+ } \
+} while (0)
+#endif
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+static uint32_t m_u32TickStep = 0UL;
+static __IO uint32_t m_u32TickCount = 0UL;
+
+#if defined(PRINT_ENABLE)
+static M4_USART_TypeDef *m_PrintfDevice;
+static uint32_t m_u32PrintfTimeout;
+#endif
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+#if defined(PRINT_ENABLE)
+/**
+ *******************************************************************************
+ ** \brief UART transmit.
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** This parameter can be one of the following values:
+ ** @arg M4_USART1: USART unit 1 instance register base
+ ** @arg M4_USART2: USART unit 2 instance register base
+ ** @arg M4_USART3: USART unit 3 instance register base
+ ** @arg M4_USART4: USART unit 4 instance register base
+ ** \param [in] cData The data for transmitting
+ **
+ ** \retval An en_result_t enumeration value:
+ ** - Ok: Send successfully
+ ** - ErrorTimeout: Send timeout
+ ** - ErrorInvalidParameter: The parameter USARTx is invalid
+ **
+ ******************************************************************************/
+static en_result_t UartPutChar(M4_USART_TypeDef *USARTx, char cData)
+{
+ uint32_t u32TxEmpty;
+ en_result_t enRet = ErrorInvalidParameter;
+ __IO uint32_t u32Timeout = m_u32PrintfTimeout;
+
+ if (NULL != USARTx)
+ {
+ /* Wait TX data register empty */
+ do
+ {
+ u32Timeout--;
+ u32TxEmpty = USARTx->SR_f.TXE;
+ } while ((u32Timeout > 0ul) && (0ul == u32TxEmpty));
+
+ if (u32TxEmpty > 0ul)
+ {
+ USARTx->DR = (uint32_t)cData;
+ enRet = Ok;
+ }
+ else
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set synchronous clock mode baudrate
+ **
+ ** \param [in] USARTx Pointer to USART instance register base
+ ** This parameter can be one of the following values:
+ ** @arg M4_USART1: USART unit 1 instance register base
+ ** @arg M4_USART2: USART unit 2 instance register base
+ ** @arg M4_USART3: USART unit 3 instance register base
+ ** @arg M4_USART4: USART unit 4 instance register base
+ ** \param [in] u32Baudrate Baudrate
+ **
+ ** \retval Ok Configure successfully.
+ ** \retval ErrorInvalidParameter USARTx is invalid
+ **
+ ******************************************************************************/
+static en_result_t SetUartBaudrate(M4_USART_TypeDef *USARTx, uint32_t u32Baudrate)
+{
+ uint32_t B;
+ uint32_t C;
+ uint32_t OVER8;
+ float32_t DIV;
+ uint64_t u64Tmp;
+ uint32_t DIV_Integer;
+ uint32_t DIV_Fraction;
+ uint32_t u32PClk1;
+ uint32_t u32UartClk;
+ en_result_t enRet = ErrorInvalidParameter;
+
+ u32PClk1 = SystemCoreClock / (1ul << (M4_SYSREG->CMU_SCFGR_f.PCLK1S));
+ u32UartClk = u32PClk1 / (1ul << (2ul * (USARTx->PR_f.PSC)));
+
+ B = u32Baudrate;
+ C = u32UartClk;
+ DIV_Fraction = 0ul;
+
+ if ((0ul != C) && (0ul != B))
+ {
+ OVER8 = USARTx->CR1_f.OVER8;
+
+ /* FBME = 0 Calculation formula */
+ /* B = C / (8 * (2 - OVER8) * (DIV_Integer + 1)) */
+ /* DIV_Integer = (C / (B * 8 * (2 - OVER8))) - 1 */
+ DIV = ((float)C / ((float)B * 8.0f * (2.0f - (float)OVER8))) - 1.0f;
+ DIV_Integer = (uint32_t)(DIV);
+
+ if ((DIV < 0.0f) || (DIV_Integer > 0xFFul))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ if ((DIV - (float32_t)DIV_Integer) > 0.00001f)
+ {
+ /* FBME = 1 Calculation formula */
+ /* B = C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256) */
+ /* DIV_Fraction = ((8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B) / C) - 128 */
+ /* E = (C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B)) - 1 */
+ /* DIV_Fraction = (((2 - OVER8) * (DIV_Integer + 1) * 2048 * B) / C) - 128 */
+ u64Tmp = (2u - (uint64_t)OVER8) * ((uint64_t)DIV_Integer + 1u) * (uint64_t)B;
+ DIV_Fraction = (uint32_t)(2048ul * u64Tmp/C - 128ul);
+ }
+
+ USARTx->CR1_f.FBME = (DIV_Fraction > 0UL) ? 1ul : 0ul;
+ USARTx->BRR_f.DIV_FRACTION = DIV_Fraction;
+ USARTx->BRR_f.DIV_INTEGER = DIV_Integer;
+ enRet = Ok;
+ }
+ }
+
+ return enRet;
+}
+
+#if defined ( __GNUC__ ) && !defined (__CC_ARM)
+/**
+ *******************************************************************************
+ ** \brief Re-target _write function.
+ **
+ ** \param [in] fd
+ ** \param [in] data
+ ** \param [in] size
+ **
+ ** \retval int32_t
+ **
+ ******************************************************************************/
+int32_t _write(int fd, char data[], int32_t size)
+{
+ int32_t i = -1;
+
+ if (NULL != data)
+ {
+ (void)fd; /* Prevent unused argument compilation warning */
+
+ for (i = 0; i < size; i++)
+ {
+ if (Ok != UartPutChar(m_PrintfDevice, data[i]))
+ {
+ break;
+ }
+ }
+ }
+
+ return i ? i : -1;
+}
+
+#else
+/**
+ *******************************************************************************
+ ** \brief Re-target fputc function.
+ **
+ ** \param [in] ch
+ ** \param [in] f
+ **
+ ** \retval int32_t
+ **
+ ******************************************************************************/
+int32_t fputc(int32_t ch, FILE *f)
+{
+ (void)f; /* Prevent unused argument compilation warning */
+
+ return (Ok == UartPutChar(m_PrintfDevice, (char)ch)) ? ch: -1;
+}
+#endif
+
+/**
+ *******************************************************************************
+ ** \brief Debug printf initialization function
+ **
+ ** \param [in] UARTx Pointer to USART instance register base
+ ** This parameter can be one of the following values:
+ ** @arg M4_USART1: USART unit 1 instance register base
+ ** @arg M4_USART2: USART unit 2 instance register base
+ ** @arg M4_USART3: USART unit 3 instance register base
+ ** @arg M4_USART4: USART unit 4 instance register base
+ ** \param [in] u32Baudrate Baudrate
+ ** \param [in] PortInit The pointer of printf port initialization function
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t UART_PrintfInit(M4_USART_TypeDef *UARTx,
+ uint32_t u32Baudrate,
+ void (*PortInit)(void))
+{
+ en_result_t enRet = ErrorInvalidParameter;
+
+ if (IS_VALID_UART(UARTx) && (0ul != u32Baudrate) && (NULL != PortInit))
+ {
+ /* Initialize port */
+ PortInit();
+
+ /* Enable clock */
+ UART_EnableClk(UARTx);
+
+ /* Initialize USART */
+ UARTx->CR1_f.ML = 0ul; /* LSB */
+ UARTx->CR1_f.MS = 0ul; /* UART mode */
+ UARTx->CR1_f.OVER8 = 1ul; /* 8bit sampling mode */
+ UARTx->CR1_f.M = 0ul; /* 8 bit data length */
+ UARTx->CR1_f.PCE = 0ul; /* no parity bit */
+
+ /* Set baudrate */
+ if(Ok != SetUartBaudrate(UARTx, u32Baudrate))
+ {
+ enRet = Error;
+ }
+ else
+ {
+ UARTx->CR2 = 0ul; /* 1 stop bit, single uart mode */
+ UARTx->CR3 = 0ul; /* CTS disable, Smart Card mode disable */
+ UARTx->CR1_f.TE = 1ul; /* TX enable */
+
+ m_PrintfDevice = UARTx;
+ m_u32PrintfTimeout = (SystemCoreClock / u32Baudrate);
+ }
+ }
+
+ return enRet;
+}
+#endif /* DDL_PRINT_ENABLE */
+
+/**
+ *******************************************************************************
+ ** \brief Delay function, delay 1ms approximately
+ **
+ ** \param [in] u32Cnt ms
+ **
+ ** \retval none
+ **
+ ******************************************************************************/
+void Ddl_Delay1ms(uint32_t u32Cnt)
+{
+ volatile uint32_t i;
+ uint32_t u32Cyc;
+
+ u32Cyc = SystemCoreClock;
+ u32Cyc = u32Cyc / 10000ul;
+ while (u32Cnt-- > 0ul)
+ {
+ i = u32Cyc;
+ while (i-- > 0ul)
+ {
+ ;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief Delay function, delay 1us approximately
+ **
+ ** \param [in] u32Cnt us
+ **
+ ** \retval none
+ **
+ ******************************************************************************/
+void Ddl_Delay1us(uint32_t u32Cnt)
+{
+ uint32_t u32Cyc;
+ volatile uint32_t i;
+
+ if(SystemCoreClock > 10000000ul)
+ {
+ u32Cyc = SystemCoreClock / 10000000ul;
+ while(u32Cnt-- > 0ul)
+ {
+ i = u32Cyc;
+ while (i-- > 0ul)
+ {
+ ;
+ }
+ }
+ }
+ else
+ {
+ while(u32Cnt-- > 0ul)
+ {
+ ;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief This function Initializes the interrupt frequency of the SysTick.
+ **
+ ** \param [in] u32Freq SysTick interrupt frequency (1 to 1000).
+ **
+ ** \retval Ok SysTick Initializes succeed
+ ** \retval Error SysTick Initializes failed
+ **
+ ******************************************************************************/
+__WEAKDEF en_result_t SysTick_Init(uint32_t u32Freq)
+{
+ en_result_t enRet = Error;
+
+ if ((0UL != u32Freq) && (u32Freq <= 1000UL))
+ {
+ m_u32TickStep = 1000UL / u32Freq;
+ /* Configure the SysTick interrupt */
+ if (0UL == SysTick_Config(SystemCoreClock / u32Freq))
+ {
+ enRet = Ok;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief This function provides minimum delay (in milliseconds).
+ **
+ ** \param [in] u32Delay Delay specifies the delay time.
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+__WEAKDEF void SysTick_Delay(uint32_t u32Delay)
+{
+ const uint32_t tickStart = SysTick_GetTick();
+ uint32_t tickEnd = u32Delay;
+ uint32_t tickMax;
+
+ if (m_u32TickStep != 0UL)
+ {
+ tickMax = 0xFFFFFFFFUL / m_u32TickStep * m_u32TickStep;
+ /* Add a freq to guarantee minimum wait */
+ if ((u32Delay >= tickMax) || ((tickMax - u32Delay) < m_u32TickStep))
+ {
+ tickEnd = tickMax;
+ }
+ while ((SysTick_GetTick() - tickStart) < tickEnd)
+ {
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ ** \brief This function is called to increment a global variable "u32TickCount".
+ ** \note This variable is incremented in SysTick ISR.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+__WEAKDEF void SysTick_IncTick(void)
+{
+ m_u32TickCount += m_u32TickStep;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Provides a tick value in millisecond.
+ **
+ ** \param None
+ **
+ ** \retval Tick value
+ **
+ ******************************************************************************/
+__WEAKDEF uint32_t SysTick_GetTick(void)
+{
+ return m_u32TickCount;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Suspend SysTick increment.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+__WEAKDEF void SysTick_Suspend(void)
+{
+ /* Disable SysTick Interrupt */
+ SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Resume SysTick increment.
+ **
+ ** \param None
+ **
+ ** \retval None
+ **
+ ******************************************************************************/
+__WEAKDEF void SysTick_Resume(void)
+{
+ /* Enable SysTick Interrupt */
+ SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
+}
+
+/**
+ *******************************************************************************
+ ** \brief ddl assert error handle function
+ **
+ ** \param [in] file Point to the current assert the wrong file
+ ** \param [in] line Point line assert the wrong file in the current
+ **
+ ******************************************************************************/
+#ifdef __DEBUG
+__WEAKDEF void Ddl_AssertHandler(uint8_t *file, int16_t line)
+{
+ /* Users can re-implement this function to print information */
+#if defined(PRINT_ENABLE)
+ printf("Wrong parameters value: file %s on line %d\r\n", file, line);
+#else
+ (void)file;
+ (void)line;
+#endif
+ for (;;)
+ {
+ ;
+ }
+}
+#endif /* __DEBUG */
+
+//@} // DdlUtilityGroup
+
+#endif /* DDL_UTILITY_ENABLE */
+
+/*******************************************************************************
+ * EOF (not truncated)
+ ******************************************************************************/
diff --git a/lib/hc32f460/driver/src/hc32f460_wdt.c b/lib/hc32f460/driver/src/hc32f460_wdt.c new file mode 100644 index 00000000..db1f1930 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_wdt.c @@ -0,0 +1,250 @@ +/*******************************************************************************
+ * 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
+ */
+/******************************************************************************/
+/** \file hc32f460_wdt.c
+ **
+ ** A detailed description is available at
+ ** @link WdtGroup Watchdog Counter description @endlink
+ **
+ ** - 2018-10-18 CDT First version for Device Driver Library of WDT.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_wdt.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup WdtGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter validity check for count cycle */
+#define IS_VALID_COUNT_CYCLE(x) \
+( (WdtCountCycle256 == (x)) || \
+ (WdtCountCycle4096 == (x)) || \
+ (WdtCountCycle16384 == (x)) || \
+ (WdtCountCycle65536 == (x)))
+
+/*!< Parameter validity check for clock division */
+#define IS_VALID_CLOCK_DIV(x) \
+( (WdtPclk3Div4 == (x)) || \
+ (WdtPclk3Div64 == (x)) || \
+ (WdtPclk3Div128 == (x)) || \
+ (WdtPclk3Div256 == (x)) || \
+ (WdtPclk3Div512 == (x)) || \
+ (WdtPclk3Div1024 == (x)) || \
+ (WdtPclk3Div2048 == (x)) || \
+ (WdtPclk3Div8192 == (x)))
+
+/*!< Parameter validity check for allow refresh percent range */
+#define IS_VALID_ALLOW_REFRESH_RANGE(x) \
+( (WdtRefresh100Pct == (x)) || \
+ (WdtRefresh0To25Pct == (x)) || \
+ (WdtRefresh25To50Pct == (x)) || \
+ (WdtRefresh0To50Pct == (x)) || \
+ (WdtRefresh50To75Pct == (x)) || \
+ (WdtRefresh0To25PctAnd50To75Pct == (x)) || \
+ (WdtRefresh25To75Pct == (x)) || \
+ (WdtRefresh0To75Pct == (x)) || \
+ (WdtRefresh75To100Pct == (x)) || \
+ (WdtRefresh0To25PctAnd75To100Pct == (x)) || \
+ (WdtRefresh25To50PctAnd75To100Pct == (x)) || \
+ (WdtRefresh0To50PctAnd75To100Pct == (x)) || \
+ (WdtRefresh50To100Pct == (x)) || \
+ (WdtRefresh0To25PctAnd50To100Pct == (x)) || \
+ (WdtRefresh25To100Pct == (x)) || \
+ (WdtRefresh0To100Pct == (x)))
+
+/*!< Parameter validity check for event request type */
+#define IS_VALID_EVENT_REQUEST_TYPE(x) \
+( (WdtTriggerInterruptRequest == (x)) || \
+ (WdtTriggerResetRequest == (x)))
+
+/*!< Parameter validity check for flag type */
+#define IS_VALID_FLAG_TYPE(x) \
+( (WdtFlagCountUnderflow == (x)) || \
+ (WdtFlagRefreshError == (x)))
+
+/*!< WDT_RR register refresh key */
+#define WDT_REFRESH_START_KEY ((uint16_t)0x0123)
+#define WDT_REFRESH_END_KEY ((uint16_t)0x3210)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief Initialize WDT function
+ **
+ ** \param [in] pstcWdtInit Pointer to WDT init configuration
+ ** \arg See the struct #stc_wdt_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t WDT_Init(const stc_wdt_init_t *pstcWdtInit)
+{
+ en_result_t enRet = Ok;
+ uint32_t regTemp;
+
+ if (NULL == pstcWdtInit)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_COUNT_CYCLE(pstcWdtInit->enCountCycle));
+ DDL_ASSERT(IS_VALID_CLOCK_DIV(pstcWdtInit->enClkDiv));
+ DDL_ASSERT(IS_VALID_ALLOW_REFRESH_RANGE(pstcWdtInit->enRefreshRange));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcWdtInit->enSleepModeCountEn));
+ DDL_ASSERT(IS_VALID_EVENT_REQUEST_TYPE(pstcWdtInit->enRequestType));
+
+ /* software start mode */
+ regTemp = ((((uint32_t)pstcWdtInit->enRequestType) << 31) | \
+ (((uint32_t)(bool)(!pstcWdtInit->enSleepModeCountEn)) << 16) | \
+ (((uint32_t)pstcWdtInit->enRefreshRange) << 8) | \
+ (((uint32_t)pstcWdtInit->enClkDiv) << 4) | \
+ ((uint32_t)pstcWdtInit->enCountCycle));
+ /* store the new value */
+ M4_WDT->CR = regTemp;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief WDT refresh counter(First refresh start count when software start)
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t WDT_RefreshCounter(void)
+{
+ en_result_t enRet = Ok;
+
+ M4_WDT->RR = WDT_REFRESH_START_KEY;
+ M4_WDT->RR = WDT_REFRESH_END_KEY;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get WDT counter current count value
+ **
+ ** \param [in] None
+ **
+ ** \retval uint16_t WDT counter current count value
+ **
+ ******************************************************************************/
+uint16_t WDT_GetCountValue(void)
+{
+ return ((uint16_t)M4_WDT->SR_f.CNT);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get WDT flag status
+ **
+ ** \param [in] enFlag WDT flag type
+ ** \arg WdtFlagCountUnderflow Count underflow flag
+ ** \arg WdtFlagRefreshError Refresh error flag
+ **
+ ** \retval Set Flag is set
+ ** \retval Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t WDT_GetFlag(en_wdt_flag_type_t enFlag)
+{
+ en_flag_status_t enFlagSta = Reset;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case WdtFlagCountUnderflow:
+ enFlagSta = (en_flag_status_t)M4_WDT->SR_f.UDF;
+ break;
+ case WdtFlagRefreshError:
+ enFlagSta = (en_flag_status_t)M4_WDT->SR_f.REF;
+ break;
+ default:
+ break;
+ }
+
+ return enFlagSta;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear WDT flag status
+ **
+ ** \param [in] enFlag WDT flag type
+ ** \arg WdtFlagCountUnderflow Count underflow flag
+ ** \arg WdtFlagRefreshError Refresh error flag
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t WDT_ClearFlag(en_wdt_flag_type_t enFlag)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
+
+ switch (enFlag)
+ {
+ case WdtFlagCountUnderflow:
+ M4_WDT->SR_f.UDF = 0u;
+ break;
+ case WdtFlagRefreshError:
+ M4_WDT->SR_f.REF = 0u;
+ break;
+ default:
+ break;
+ }
+
+ return enRet;
+}
+
+//@} // WdtGroup
+
+/******************************************************************************
+ * EOF (not truncated)
+ *****************************************************************************/
|