/**
  ******************************************************************************
  * @file    kpm32xx_ddl_timh.c
  * @author  Kiwi Software Team
  * @brief   TIMH DDL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the TIMH peripheral:
  *          1.peripheral initializes and deInitializes
  *          2.different mode of PWM output operation
  *          3.yPCI and overwirte functions
  * @note
  *          V1.0.0, 2024/12/20.
  *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *
  *   3. Neither the name of the copyright holder nor the names of its contributors
  *      may be used to endorse or promote products derived from this software without
  *      specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  ******************************************************************************
  */

#include "kpm32xx_ddl.h"
#include <string.h>


#ifdef DDL_TIMH_MODULE_ENABLED


/**
  * @brief  use to activate TIMH module
  * @param  None
  * @retval None
  */
void DDL_TIMH_Instance_Activate(void)
{
	__DDL_RCC_TIMH_ACTIVE();
	__DDL_RCC_TIMH_CLK_RELEASE();
}


/**
  * @brief  Configure the structure of TIMH_ClkInit_T to default values.
  * @param  pTimhClk : Pointer to a TIMH_ClkInit_T structure.
  * @retval None
  */
void DDL_TIMH_ClkStructInit(TIMH_ClkInit_T *pTimhClk)
{
	pTimhClk->clockDivision  = TIMH_CLOCKDIVISION_DIV2;
	pTimhClk->frequencyScale = 0;
	pTimhClk->FSMINPER       = 0;
}


/**
  * @brief  use to config TIMH common clock
  * @param  clkConfig : pointer to a TIMH_Clk_Config_T structure.
  * @retval None
  */
void DDL_TIMH_Clock_Init(TIMH_ClkInit_T *clkConfig)
{
	uint32_t tmp_clkcon = 0;

	tmp_clkcon = TIMH_COMMON->PCLKCON;
	tmp_clkcon &= ~TIMH_PCLKCON_DIVSEL;
	/*config clock division, frequency scale, frequency scaling Minimum period*/
	tmp_clkcon |= clkConfig->clockDivision;

	TIMH_COMMON->PCLKCON 	= tmp_clkcon;
	TIMH_COMMON->FSCL		= clkConfig->frequencyScale;
	TIMH_COMMON->FSMINPER	= clkConfig->FSMINPER;
}


/**
  * @brief  Configure the structure of TIMH_BaseInit_T to default values.
  * @param  pTimhStruct : Pointer to a TIMH_BaseInit_T structure.
  * @retval None
  */
void DDL_TIMH_BaseStructInit(TIMH_BaseInit_T *pTimhStruct)
{
	memset(pTimhStruct, 0, sizeof(TIMH_BaseInit_T)/sizeof(uint8_t));
}


/**
  * @brief  Initializes TIMH by the specified parameters in the TIMH_BaseInit_T.
  * @param  TIMHx       : TIMH instance.
  *         pTimhStruct : Pointer to a TIMH_BaseInit_T structure.
  * @retval None
  */
void DDL_TIMH_Init(TIMH_Type *TIMHx, TIMH_BaseInit_T *pTimhStruct)
{
	uint32_t tmp_clkcon = 0, tmp_pgcon = 0;
	uint32_t timeout = 0;

	tmp_clkcon = TIMH_COMMON->PCLKCON;
	tmp_pgcon  = TIMHx->CON;

	/*if hr_mode selected, set PCLKCON[HRWORK]*/
	if(pTimhStruct->hrModeEnable)
	{
		tmp_clkcon |= TIMH_PCLKCON_HRWORK;
		TIMH_COMMON->PCLKCON = tmp_clkcon;

		do
		{
			/*check hr_mode ready or not*/
			if(TIMH_COMMON->PCLKCON & TIMH_PCLKCON_HRRDY)
			{
				break;
			}
			timeout++;
		}
		while( timeout < TIMH_HR_MODE_STARTUP_TIMEOUT );

		/*if start hr_mode failed, reset PCLKCON[HRWORK]*/
		if((TIMH_COMMON->PCLKCON & TIMH_PCLKCON_HRERR) ||
			timeout >= TIMH_HR_MODE_STARTUP_TIMEOUT)
		{
			pTimhStruct->hrModeEnable = TIMH_HR_MODE_DISABLE;
			tmp_clkcon &= ~TIMH_PCLKCON_HRWORK;
			TIMH_COMMON->PCLKCON = tmp_clkcon;
		}
	}
	else
	{
		TIMH_COMMON->PCLKCON = tmp_clkcon;
	}

	/* config deadtime */
	TIMHx->DT0 = (((uint32_t)pTimhStruct->deadTime.DTH)<<16) |
				 ((uint32_t)pTimhStruct->deadTime.DTL);

	/* congfig trigA/B/C */
	TIMHx->TRIGA = pTimhStruct->trig_xValue.trgiA;
	TIMHx->TRIGB = pTimhStruct->trig_xValue.trgiB;
	TIMHx->TRIGC = pTimhStruct->trig_xValue.trgiC;

	TIMHx->PER   = ((uint32_t)pTimhStruct->period       & 0x1fffff);
	TIMHx->PHASE = ((uint32_t)pTimhStruct->phase        & 0x1fffff);
	TIMHx->DC    = ((uint32_t)pTimhStruct->dutyCycle    & 0x1fffff);
	TIMHx->DCA   = ((uint32_t)pTimhStruct->dutyCycleAdj & 0x1fff  );
	/* set STAT[UPDREQ] 1 to update data to REG */
	TIMHx->STAT |= TIMH_PGxSTAT_UPDREQ;

	/* config update mode */
	TIMHx->CON &= (~(TIMH_PGxCON_UPDMOD));

	/*set PGx running mode*/
	tmp_pgcon &= ~TIMH_PGxCON_MODSEL;
	tmp_pgcon |= (uint32_t)pTimhStruct->counterMode;

	/*config clock source*/
	tmp_pgcon &= ~TIMH_PGxCON_CLKSEL;
	/*if hr_mode enable, set PGxCON[HREN]*/
	if(pTimhStruct->hrModeEnable)
	{
		tmp_pgcon |= TIMH_HR_MODE_ENABLE;
		pTimhStruct->clockSource = TIMHx_CLOCKSOURCE_CLK_IN;
	}
	tmp_pgcon |= (uint32_t)pTimhStruct->clockSource;

	TIMHx->CON = tmp_pgcon;
	/* config update mode */
	MODIFY_REG(TIMHx->CON,
	           TIMH_PGxCON_UPDMOD,
	           ((pTimhStruct->updateMode) << TIMH_PGxCON_UPDMOD_Pos));

	/* config polarity of pwm_H and pwm_L */
	MODIFY_REG( TIMHx->IOCON,
	           (TIMH_PGxIOCON_POLH|TIMH_PGxIOCON_POLL),
	           ((pTimhStruct->pwm_hPolarity << TIMH_PGxIOCON_POLH_Pos) |
	            (pTimhStruct->pwm_lPolarity << TIMH_PGxIOCON_POLL_Pos)) );

	/* config output mode and enable PENH/L output*/
	MODIFY_REG( TIMHx->IOCON,
	           (TIMH_PGxIOCON_PMOD | TIMH_PGxIOCON_PENH | TIMH_PGxIOCON_PENL),
	           ((pTimhStruct->outputMode) | TIMH_PGxIOCON_PENH | TIMH_PGxIOCON_PENL) );
}


/**
  * @brief  Start pwm
  * @param  TIMHx : TIMH instance.
  * @retval None
  */
void DDL_TIMH_PWM_Start(TIMH_Type *TIMHx)
{
	/* Enable the Peripheral, set PGxCON[ON] */
	__DDL_TIMH_ENABLE(TIMHx);
	/* set PGx[TRSET] to start pwm */
	__DDL_TIMH_TRSET_SET(TIMHx);
}


/**
  * @brief  Stop pwm
  * @param  TIMHx : TIMH instance.
  * @retval None
  */
void DDL_TIMH_PWM_Stop(TIMH_Type *TIMHx)
{
	/* set PGx[TRCLR] to stop pwm */
	__DDL_TIMH_TRCLR_CLER(TIMHx);
	/* Disable the Peripheral */
	__DDL_TIMH_DISABLE(TIMHx);
}


/**
  * @brief  TIMH interrupt enable
  * @param  TIMHx    : TIMH instance.
  *         intrMask : search
  *                    @defgroup TIMH_IEVT_Intr_Selection
  *                    @defgroup TIMH_yPCI_Intr_Selection.
  * @retval None
  */
void DDL_TIMH_IntEnable(TIMH_Type *TIMHx, uint32_t intrMask)
{
	__DDL_TIMHx_IT_EN(TIMHx, intrMask);
}


/**
  * @brief  TIMH interrupt disable
  * @param  TIMHx    : TIMH instance.
  *         intrMask : search
  *                    @defgroup TIMH_IEVT_Intr_Selection
  *                    @defgroup TIMH_yPCI_Intr_Selection.
  * @retval None
  */
void DDL_TIMH_IntDisable(TIMH_Type *TIMHx, uint32_t intrMask)
{
	__DDL_TIMHx_IT_DIS(TIMHx, intrMask);
}


/**
  * @brief  Configure the structure of TIMH_Overwrite_T to default values.
  * @param  overWrite : Pointer to a TIMH_Overwrite_T structure.
  * @retval None
  */
void DDL_TIMH_Overwrite_StructInit(TIMH_Overwrite_T *overWrite)
{
	memset(overWrite, 0, sizeof(TIMH_Overwrite_T)/sizeof(uint8_t));
}


/**
  * @brief  Config overwirte value and behave mode for xPCI and sofeware control
  * @param  TIMHx     : TIMH instance.
  *         overWrite : pointer to a TIMH_Overwrite_T structure.
  * @retval None
  */
void DDL_TIMH_Overwrite_Config(TIMH_Type *TIMHx, TIMH_Overwrite_T *overWrite)
{
	uint32_t tempOverWrite = 0;

	tempOverWrite = TIMHx->IOCON;

	/*reset PGxIOCON[0:14] to 0*/
	tempOverWrite &= (~(TIMH_PGxIOCON_DBDAT |TIMH_PGxIOCON_FFDAT |TIMH_PGxIOCON_CLDAT |
	                    TIMH_PGxIOCON_FLTDAT|TIMH_PGxIOCON_OSYNC |TIMH_PGxIOCON_OVRDAT|
	                    TIMH_PGxIOCON_OVRENL|TIMH_PGxIOCON_OVRENH|TIMH_PGxIOCON_SWAP  |
	                    TIMH_PGxIOCON_IDAT));

	/* config value of overwrite bits */
	tempOverWrite |= *((uint32_t *)overWrite);
	TIMHx->IOCON = tempOverWrite;
}


/**
  * @brief  Configure the structure of TIMH_yPCI_Init_T to default values.
  * @param  pTimhStruct : Pointer to a TIMH_BaseInit_T structure.
  * @retval None
  */
void DDL_TIMH_yPCI_StructInit(TIMH_yPCI_Init_T *yPCI)
{
	memset(yPCI, 0, sizeof(TIMH_yPCI_Init_T)/sizeof(uint8_t));
}


/**
  * @brief  use to stepup SPCI module.(SPCI is used for start a PWM period)
  * @param  TIMHx : TIMH instance.
  *         yPCI  : pointer to a TIMH_yPCI_Init_T structure for SPCI setup.
  * @retval None
  */
void DDL_TIMH_SPCI_Setup(TIMH_Type *TIMHx, TIMH_yPCI_Init_T *yPCI)
{
	TIMHx->SPCI = (*( (uint32_t *)yPCI ));
}


/**
  * @brief  use to stepup SPCI module with bypass source
  * @param  TIMHx         : TIMH instance.
  *         pci_init      : pointer to a TIMH_yPCI_Init_T structure for SPCI setup.
  *         bypass_source : pointer to a TIMH_PCI_BPSEL_T structure for bypass source.
  * @retval None
  */
void DDL_TIMH_SPCI_Bypass_Setup(TIMH_Type        *TIMHx,
                                TIMH_yPCI_Init_T *yPCI,
                                TIMH_PCI_BPSEL_T bypass_source)
{
	yPCI->bypassEnable    = PCI_BYPASS_ENABLE;
	yPCI->bypassSourceSel = bypass_source;
	DDL_TIMH_SPCI_Setup(TIMHx,yPCI);
}


/**
  * @brief  use to stepup FPCI module
  * @param  TIMHx     : TIMH instance.
  *         yPCI      : pointer to a TIMH_yPCI_Init_T structure for FPCI setup.
  *         overWrite : pointer to a TIMH_Overwrite_T structure for FPCI overwrite value.
  * @retval None
  */
void DDL_TIMH_FPCI_Setup(TIMH_Type        *TIMHx,
                         TIMH_yPCI_Init_T *yPCI,
                         TIMH_Overwrite_T *overWrite)
{
	DDL_TIMH_Overwrite_Config(TIMHx, overWrite);
	TIMHx->FPCI = (*( (uint32_t *)yPCI ));
}


/**
  * @brief  use to stepup FPCI module with bypass source
  * @param  TIMHx         : TIMH instance.
  *         yPCI          : pointer to a TIMH_yPCI_Init_T structure for FPCI setup.
  *         overWrite     : pointer to a TIMH_Overwrite_T structure for FPCI overwrite value.
  *         bypass_source : pointer to a TIMH_PCI_BPSEL_T structure for bypass source.
  * @retval None
  */
void DDL_TIMH_FPCI_Bypass_Setup(TIMH_Type        *TIMHx,
                                TIMH_yPCI_Init_T *yPCI,
                                TIMH_Overwrite_T *overWrite,
                                TIMH_PCI_BPSEL_T bypass_source)
{
	yPCI->bypassEnable    = PCI_BYPASS_ENABLE;
	yPCI->bypassSourceSel = bypass_source;
	DDL_TIMH_FPCI_Setup(TIMHx, yPCI, overWrite);
}

/**
  * @brief  use to stepup CLPCI module
  * @param  TIMHx     : TIMH instance.
  *         yPCI      : pointer to a TIMH_yPCI_Init_T structure for CLPCI setup.
  *         overWrite : pointer to a TIMH_Overwrite_T structure for CLPCI overwrite value.
  * @retval None
  */
void DDL_TIMH_CLPCI_Setup(TIMH_Type        *TIMHx,
                          TIMH_yPCI_Init_T *yPCI,
                          TIMH_Overwrite_T *overWrite)
{
	DDL_TIMH_Overwrite_Config(TIMHx, overWrite);
	TIMHx->CLPCI = (*( (uint32_t *)yPCI ));
}


/**
  * @brief  use to stepup CLPCI module with bypass source
  * @param  TIMHx         : TIMH instance.
  *         yPCI          : pointer to a TIMH_yPCI_Init_T structure for CLPCI setup.
  *         overWrite     : pointer to a TIMH_Overwrite_T structure for CLPCI overwrite value.
  *         bypass_source : pointer to a TIMH_PCI_BPSEL_T structure for bypass source.
  * @retval None
  */
void DDL_TIMH_CLPCI_Bypass_Setup(TIMH_Type        *TIMHx,
                                 TIMH_yPCI_Init_T *yPCI,
                                 TIMH_Overwrite_T *overWrite,
                                 TIMH_PCI_BPSEL_T bypass_source)
{
	yPCI->bypassEnable    = PCI_BYPASS_ENABLE;
	yPCI->bypassSourceSel = bypass_source;
	DDL_TIMH_CLPCI_Setup(TIMHx, yPCI, overWrite);
}


/**
  * @brief  use to stepup FFPCI module
  * @param  TIMHx     : TIMH instance.
  *         yPCI      : pointer to a TIMH_yPCI_Init_T structure for FFPCI setup.
  *         overWrite : pointer to a TIMH_Overwrite_T structure for FFPCI overwrite value.
  * @retval None
  */
void DDL_TIMH_FFPCI_Setup(TIMH_Type        *TIMHx,
                          TIMH_yPCI_Init_T *yPCI,
                          TIMH_Overwrite_T *overWrite)
{
	DDL_TIMH_Overwrite_Config(TIMHx, overWrite);
	TIMHx->FFPCI = (*( (uint32_t *)yPCI ));
}


/**
  * @brief  use to stepup FFPCI module with bypass source
  * @param  TIMHx         : TIMH instance.
  *         yPCI          : pointer to a TIMH_yPCI_Init_T structure for FFPCI setup.
  *         overWrite     : pointer to a TIMH_Overwrite_T structure for FFPCI overwrite value.
  *         bypass_source : pointer to a TIMH_PCI_BPSEL_T structure for bypass source.
  * @retval None
  */
void DDL_TIMH_FFPCI_Bypass_Setup(TIMH_Type        *TIMHx,
                                 TIMH_yPCI_Init_T *yPCI,
                                 TIMH_Overwrite_T *overWrite,
                                 TIMH_PCI_BPSEL_T bypass_source)
{
	yPCI->bypassEnable    = PCI_BYPASS_ENABLE;
	yPCI->bypassSourceSel = bypass_source;
	DDL_TIMH_FFPCI_Setup(TIMHx, yPCI, overWrite);
}


/**
  * @brief  use to config LEB funtion
  * @param  TIMHx        : TIMH instance.
  *         lebPeriod    : Leading-Edge Blanking Period
  *                        if TIMHx clk is 48Mhz, LEB time length = ( ((LEBP[15:0]>>3)+1) * 8 ) / 48000000
  *         lebTrigerSel : point to a TIMH_LEB_T for config LEB trige source
  * @retval None
  */
void DDL_TIMH_LEB_Config(TIMH_Type  *TIMHx,
	                     uint16_t   lebPeriod,
	                     TIMH_LEB_T *lebTrigerSel)
{
	static uint32_t tmp = 0;

	/* reset PGxLEB[0:19] to 0 */
	TIMHx->LEB &= (~(TIMH_PGxLEB_LEBP|TIMH_PGxLEB_PLF|
	                 TIMH_PGxLEB_PLR |TIMH_PGxLEB_PHF|TIMH_PGxLEB_PHR));
	/* set leb period */
	lebTrigerSel->LEB_Period = (lebPeriod & 0xFFF8);

	/* config value of LEB bits */
	tmp = *((uint32_t *)lebTrigerSel);
	TIMHx->LEB |= tmp;
}


/**
  * @brief  This API is used to config adc triger funtion.
  * @param  TIMHx                 : TIMH instance.
  *         adcTrig1_FreqDiv      : ADC_Triger1 frequncey division
  *         adcTrig1_Offset       : ADC_Triger1 start offset
  *         htim adtr1TRIGA       : TRIGA as ADC_Triger1's source
  *         htim adtr1TRIGB       : TRIGB as ADC_Triger1's source
  *         htim adtr1TRIGC       : TRIGC as ADC_Triger1's source
  *         htim adtr2TRIGA       : TRIGA as ADC_Triger2's source
  *         htim adtr2TRIGB       : TRIGB as ADC_Triger2's source
  *         htim adtr2TRIGC       : TRIGC as ADC_Triger2's source
  * @retval None
  */
void DDL_TIMH_ADC_Triger_Config(TIMH_Type            *TIMHx,
	                            uint8_t              adcTrig1_FreqDiv,
	                            uint8_t              adcTrig1_Offset,
	                            TIMH_ADC_Trg_EN_T    adtr1TRIGA,
	                            TIMH_ADC_Trg_EN_T    adtr1TRIGB,
	                            TIMH_ADC_Trg_EN_T    adtr1TRIGC,
	                            TIMH_ADC_Trg_EN_T    adtr2TRIGA,
	                            TIMH_ADC_Trg_EN_T    adtr2TRIGB,
	                            TIMH_ADC_Trg_EN_T    adtr2TRIGC )
{
	TIMH_ADC_Trige_T adcTrigerBits = {0};
	TIMH_ADC_Trige_T *ptr = &adcTrigerBits;
	uint32_t tmp = 0;

	/*reset PGxEVT[8:23] = 0*/
	tmp = TIMH_PGxEVT_ADTR1EN1|TIMH_PGxEVT_ADTR1EN2|TIMH_PGxEVT_ADTR1EN3|
		  TIMH_PGxEVT_ADTR1PS |TIMH_PGxEVT_ADTR1OFS|TIMH_PGxEVT_ADTR2EN1|
		  TIMH_PGxEVT_ADTR2EN2|TIMH_PGxEVT_ADTR2EN3;
	TIMHx->EVT &= (~tmp);

	adcTrigerBits.ADTR1EN1 = adtr1TRIGA;
	adcTrigerBits.ADTR1EN2 = adtr1TRIGB;
	adcTrigerBits.ADTR1EN3 = adtr1TRIGC;
	adcTrigerBits.ADTR1PS  = adcTrig1_FreqDiv;
	adcTrigerBits.ADTR1OFS = adcTrig1_Offset;
	adcTrigerBits.ADTR2EN1 = adtr2TRIGA;
	adcTrigerBits.ADTR2EN2 = adtr2TRIGB;
	adcTrigerBits.ADTR2EN3 = adtr2TRIGC;

	tmp = *((uint32_t *)ptr);
	tmp <<= 8;
	TIMHx->EVT |= tmp;
}


/**
  * @brief  TIMH Capture Config
  * @param  TIMHx      : TIMH instance.
  *         captureSrc : value from 0x00 to 0x04, refer to 
  *                      @defgroup TIMH_Caputer_Source
  * @retval None
  */
void DDL_TIMH_Capture_Config(TIMH_Type *TIMHx, uint8_t captureSrc)
{
	static uint8_t capSrc_tmp = 0;

	capSrc_tmp = (captureSrc & 0x07);

	/*clean STAT[CAP]*/
	TIMHx->STAT |= TIMH_PGxSTAT_CAP;
	/* congfig capture source */
	MODIFY_REG(TIMHx->IOCON, TIMH_PGxIOCON_CAPSRC, (capSrc_tmp<<TIMH_PGxIOCON_CAPSRC_Pos));
}


/**
  * @brief  Get TIMHx Capture value
  * @param  TIMHx        : TIMH instance.
  *         captureValue : value of PGxCAP
  * @retval None
  */
void DDL_TIMH_Get_Capture_Value(TIMH_Type *TIMHx, uint32_t *captureValue)
{
	uint32_t timeout = 0;

	/* if capture source is sofeware */
	if((TIMHx->IOCON & TIMH_PGxIOCON_CAPSRC) == 0)
	{
		/* start capture */
		TIMHx->CAP = 1;
	}

	/*wait for STAT[CAP] = 1*/
	do
	{
		/*check capture finish or not*/
		if(TIMHx->STAT & TIMH_PGxSTAT_CAP)
		{
			/* get capture value */
			*captureValue = TIMHx->CAP;
			/*clean STAT[CAP]*/
			TIMHx->STAT |= TIMH_PGxSTAT_CAP;
			break;
		}
		timeout++;
	}
	while( timeout < TIMH_CAP_NOT_READY_TIMEOUT );

	if(timeout >= TIMH_CAP_NOT_READY_TIMEOUT)
	{
		return;
	}
}


/**
  * @brief  combine output config
  * @param  combSource1Sel   : combine  source1 select
  *         combSource0Sel   : combine  source0 select
  *         combSource1Pol   : combine  source1 polarity config
  *         combSource0Pol   : combine  source0 polarity config
  *         logicFunctionSel : logic function select
  *         logicOutputSel   : logic output select
  * @retval None
  *
  */
void DDL_TIMH_COMB_OUTPUT_CONFIG(uint8_t combSource1Sel,   uint8_t combSource0Sel,
                                 uint8_t combSource1Pol,   uint8_t combSource0Pol,
                                 uint8_t logicFunctionSel, uint8_t logicOutputSel)
{
	uint32_t tmp = 0;

	/* combine PWM logic output target select */
	if (logicOutputSel <= 3)
	{
		tmp |= (logicOutputSel << TIMH_LOGCONy_PWMLFyD_Pos);
	}
	else
	{
		return;
	}

	/* combine PWM logic function select */
	if (logicFunctionSel <= 3)
	{
		tmp |= (logicFunctionSel << TIMH_LOGCONy_PWMLFy_Pos);
	}
	else
	{
		return;
	}

	/* combine PWM logic source 0 polarity */
	if (combSource0Pol <= 1)
	{
		tmp |= (combSource0Pol << TIMH_LOGCONy_S0yPOL_Pos);
	}
	else
	{
		return;
	}
	/* combine PWM logic source 1 polarity */
	if (combSource1Pol <= 1)
	{
		tmp |= (combSource1Pol << TIMH_LOGCONy_S1yPOL_Pos);
	}
	else
	{
		return;
	}

	/* combine PWM logic source 0 select */
	if (combSource0Sel <= 5)
	{
		tmp |= (combSource0Sel << TIMH_LOGCONy_PWMS0y_Pos);
	}
	else
	{
		return;
	}
	/* combine PWM logic source 1 select */
	if (combSource1Sel <= 5)
	{
		tmp |= (combSource1Sel << TIMH_LOGCONy_PWMS1y_Pos);
	}
	else
	{
		return;
	}

	/* set in register */
	TIMH_COMMON->LOGCONA = tmp;
}


/**
  * @brief  event output register config
  * @param  pwmEventCtrl     : select PWM event output control register
  *         eventOutputDelay : PWM event output delay control
  *                            0 (delay 8 clock)
  *                            1 (no delay     )
  *         pwmEventSel      : PWM event select
  *         pwmSourceSel     : PWM event source select
  * @retval None
  */
void DDL_Event_Output_Config(TIMH_PWM_EVENT_CTRL_T pwmEventCtrl,
                             uint8_t               eventOutputDelay,
                             TIMH_EBUS_EVENT_T     pwmEventSel,
                             TIMH_EBUS_SOURCE_T    pwmSourceSel)
{
	uint32_t tmp = 0;
	
	tmp |= eventOutputDelay << TIMH_PWMEVTy_EVTySTRD_Pos;
	tmp |= pwmEventSel      << TIMH_PWMEVTy_EVTySEL_Pos;
	tmp |= pwmSourceSel     << TIMH_PWMEVTy_EVTyPGS_Pos;
	
	switch (pwmEventCtrl)
	{
		case TIMH_EVENT_A:
			TIMH_COMMON ->PWMEVTA |= tmp;
			break;
		case TIMH_EVENT_B:
			TIMH_COMMON ->PWMEVTB |= tmp;
			break;
		case TIMH_EVENT_C:
			TIMH_COMMON ->PWMEVTC |= tmp;
			break;
	}
}


/**
  * @brief  deadtime config, clk = 200M(IC), dtime = xx us
  * @param  TIMHx  : TIMH instance.
  *         dtimeF : failing
  *         dtimeR : rising
  * @retval None
  */
void DDL_TIMH_DeadTime_Init(TIMH_Type *TIMHx,
	                        uint16_t  dtimeF,
	                        uint16_t  dtimeR)
{
	TIMHx->DT0 = ((dtimeR<<16) + dtimeF);
	__DDL_TIMH_UPDREQ(TIMHx);
}

#endif /*DDL_TIMH_MODULE_ENABLED*/

