/*******************************************************************************
*                  COPYRIGHT (C) 2021 CMS Technologies Ltd.                    *
*                                                                              *
********************************************************************************
* FileName      : timm.c                                                  *
* Author        :                                                              *
* Version       : 1.0.2                                                          *
* Date          : 2024.03.29                                                   *
* Description   :                                                              *
* Function List :                                                              *
********************************************************************************/
#include "timm.h"
#include "cgc.h"

static TMM_REG_t TMM_reg;
volatile uint16_t tmm_overflow_count_a = 0U;
volatile uint16_t tmm_overflow_count_b = 0U;


/***********************************************************************************************************************
* Function Name: TMM_RegSetting
* @brief  this function is to mapping TMM reg
* @param   
* @return   
***********************************************************************************************************************/	
void TMM_RegSetting(TMMSelect_TypeDef TMMx)
{
	switch (TMMx)
	{
		case TMM0:
			TMM_reg.TMMR  = &TMM->TMMR;
			TMM_reg.TMPMR = &TMM->TMPMR;
			TMM_reg.TMFCR = &TMM->TMFCR;				
			TMM_reg.TMOCR = &TMM->TMOCR;
			TMM_reg.TMCR[0] = &TMM->TMCR0;
			TMM_reg.TMIORA[0] = &TMM->TMIORA0;
			TMM_reg.TMIORC[0] = &TMM->TMIORC0;
			TMM_reg.TMIER[0] = &TMM->TMIER0;
		    TMM_reg.TMPOCR[0] = &TMM->TMPOCR0;
			TMM_reg.TMSR  = &TMM->TMSR0;
		
			TMM_reg.TMGRA = &TMM->TMGRA0;
			TMM_reg.TMGRB = &TMM->TMGRB0;
			TMM_reg.TMGRC = &TMM->TMGRC0;
			TMM_reg.TMGRD = &TMM->TMGRD0;

			TMM_reg.OPTL0 = &TMM->OPCTL0;
			TMM_reg.TMOER1 = &TMM->TMOER1;		
			TMM_reg.TMDF[0] = &TMM->TMDF0;		
			break;
		case TMM1:
			TMM_reg.TMMR  = &TMM->TMMR;
			TMM_reg.TMPMR = &TMM->TMPMR;
			TMM_reg.TMFCR = &TMM->TMFCR;
			TMM_reg.TMOCR = &TMM->TMOCR;		
			TMM_reg.TMCR[1] = &TMM->TMCR1;
			TMM_reg.TMIORA[1] = &TMM->TMIORA1;
			TMM_reg.TMIORC[1] = &TMM->TMIORC1;
			TMM_reg.TMIER[1] = &TMM->TMIER1;
		    TMM_reg.TMPOCR[1] = &TMM->TMPOCR1;
			TMM_reg.TMSR  = &TMM->TMSR1;
		
   		    TMM_reg.TMGRA = &TMM->TMGRA1;
			TMM_reg.TMGRB = &TMM->TMGRB1;
			TMM_reg.TMGRC = &TMM->TMGRC1;
			TMM_reg.TMGRD = &TMM->TMGRD1;
		
			TMM_reg.OPTL0 = &TMM->OPCTL0;
			TMM_reg.TMOER1 = &TMM->TMOER1;
			TMM_reg.TMDF[1] = &TMM->TMDF1;
			break;
		default:
			break;
	}
}
/**
  * @brief  Initializes the TIEMRM peripheral according to the specified
  *         parameters in the TIMM_InitStruct .
  * @param  TIMM_InitStruct: pointer to a TMM_InitTypeDef structure that contains
  *         the configuration information for the specified TIEMRM peripheral.
  * @retval none
  */
void TMM_Init(TMM_InitTypeDef *TMM_InitStruct)
{
	assert_param(IS_TMM_CLOCK(TMM_InitStruct->TMM_Clk));	
	assert_param(IS_TMM_CHANNEL(TMM_InitStruct->TMM_Channel));	

	CGC_PER1PeriphClockCmd(CGC_PER1Periph_TMM,ENABLE);
	TMM_RegSetting(TMM_InitStruct->TMM_Select);
	/*reset tmm counter and set conuter mode when compare match*/
	if(TMM_InitStruct->TMM_Select == TMM0)
	{
		TMM->TMSTR &= (uint8_t)~(_01_TMM_TM0_COUNT_START);
		TMM->TMSTR |= _04_TMM_TM0_COUNT_CONTINUES; 
	}
	else
	{
		TMM->TMSTR &= (uint8_t)~(_01_TMM_TM0_COUNT_START << TMM_InitStruct->TMM_Select);
		TMM->TMSTR |= _04_TMM_TM0_COUNT_CONTINUES << TMM_InitStruct->TMM_Select; 
	}
	if((TMM_InitStruct->TMM_Clk == TMM_FCLK_TMCLK) && TMM_InitStruct->TMM_Mode != ( TMM_Mode_PWM3))
	{
		*TMM_reg.TMFCR |= 0x40;  // input clock is valid
	}

	if(TMM_InitStruct->TMM_Mode == TMM_Mode_Capture)
	{
		*TMM_reg.TMMR |= 0x00 | (TMM_InitStruct->TMM_CHD_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 5 |\
						(TMM_InitStruct->TMM_CHC_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 4;		
		*TMM_reg.TMDF[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_IC.TMM_Filter_Clk;
		*TMM_reg.TMCR[TMM_InitStruct->TMM_Select] = TMM_InitStruct->TMM_CounterClear | TMM_InitStruct->TMM_Clk;
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_A) == TMM_Channel_A)
		{
			*TMM_reg.TMIORA[TMM_InitStruct->TMM_Select] |= 0x04 | TMM_InitStruct->TMM_IC.TMM_CHA.TMM_ICPolarity;
			*TMM_reg.TMDF[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_IC.TMM_CHA.TMM_ICFilter;
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_B)== TMM_Channel_B)               
		{
			*TMM_reg.TMIORA[TMM_InitStruct->TMM_Select] |= 0x40 | (TMM_InitStruct->TMM_IC.TMM_CHB.TMM_ICPolarity << 4);  //??????
			*TMM_reg.TMDF[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_IC.TMM_CHB.TMM_ICFilter << 1;			
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_C)== TMM_Channel_C)
		{
			*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= 0x08 |0x04 | TMM_InitStruct->TMM_IC.TMM_CHC.TMM_ICPolarity;	
			*TMM_reg.TMDF[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_IC.TMM_CHC.TMM_ICFilter << 2;			
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_D)== TMM_Channel_D)
		{
			*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= 0x80 |0x40 | (TMM_InitStruct->TMM_IC.TMM_CHD.TMM_ICPolarity << 4);	//??????
			*TMM_reg.TMDF[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_IC.TMM_CHD.TMM_ICFilter << 3;			
		}		
	}
	if(TMM_InitStruct->TMM_Mode == TMM_Mode_Compare)
	{
		*TMM_reg.TMMR |= 0x00 | (TMM_InitStruct->TMM_CHD_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 5 |\
						(TMM_InitStruct->TMM_CHC_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 4 ;        
		*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] &= 0x00;
		*TMM_reg.TMCR[TMM_InitStruct->TMM_Select] = TMM_InitStruct->TMM_CounterClear | TMM_InitStruct->TMM_Clk; //counter cleared condition 	
		
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_A) == TMM_Channel_A)
		{
			*TMM_reg.TMIORA[TMM_InitStruct->TMM_Select] |= (TMM_InitStruct->TMM_OC.TMM_CHA.TMM_OCPolarity);	
			*TMM_reg.TMGRA = TMM_InitStruct->TMM_CHA_Pulse - 1;	
			*TMM_reg.TMOER1 &= ~((TMM_Channel_A) << (TMM_InitStruct->TMM_Select << 2));	// 0x00 ???????????????
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_B)== TMM_Channel_B)
		{
			*TMM_reg.TMIORA[TMM_InitStruct->TMM_Select] |= ((TMM_InitStruct->TMM_OC.TMM_CHB.TMM_OCPolarity)<< 4);
			*TMM_reg.TMGRB = TMM_InitStruct->TMM_CHB_Pulse - 1;		
			*TMM_reg.TMOER1 &= ~((TMM_Channel_B) << (TMM_InitStruct->TMM_Select << 2));		
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_C)== TMM_Channel_C)
		{
			*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= (TMM_InitStruct->TMM_OC.TMM_CHC.TMM_OCPolarity);	
			*TMM_reg.TMGRC = TMM_InitStruct->TMM_CHC_Pulse - 1;		
			*TMM_reg.TMOER1 &= ~((TMM_Channel_C) << (TMM_InitStruct->TMM_Select << 2));
			if(TMM_InitStruct->TMM_OC.TMM_CHC_OutPin_Ctrl == TMM_OC_Output_PinCtrl_Enable)
			{
				*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= 0x00; 
				if(TMM_InitStruct->TMM_CHC_AS_BufferRegister)
				{
					*TMM_reg.TMMR &= ~ (TMM_InitStruct->TMM_CHC_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 4;
				}					
			}
			else
			{
				*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= 0x08; // use TMGRC to control TMIOA pin output
			}
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_D)== TMM_Channel_D)
		{
			*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= ((TMM_InitStruct->TMM_OC.TMM_CHD.TMM_OCPolarity)<< 4);	
			*TMM_reg.TMGRD = TMM_InitStruct->TMM_CHD_Pulse - 1;		
			*TMM_reg.TMOER1 &= ~((TMM_Channel_D) << (TMM_InitStruct->TMM_Select << 2));
			if(TMM_InitStruct->TMM_OC.TMM_CHD_OutPin_Ctrl == TMM_OC_Output_PinCtrl_Enable)
			{
				*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= 0x00; 
				if(TMM_InitStruct->TMM_CHD_AS_BufferRegister)
				{
					*TMM_reg.TMMR &= ~ (TMM_InitStruct->TMM_CHD_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 5;
				}					
			}
			else
			{
				*TMM_reg.TMIORC[TMM_InitStruct->TMM_Select] |= 0x80; // use TMGRD to control TMIOB pin output
			}
		}	
	}
	
	if(TMM_InitStruct->TMM_Mode == TMM_Mode_PWM || TMM_InitStruct->TMM_Mode == TMM_Mode_PWM_RSTSYN )
	{
		*TMM_reg.TMMR |= 0x00 | (TMM_InitStruct->TMM_CHD_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 5 |\
						(TMM_InitStruct->TMM_CHC_AS_BufferRegister << (TMM_InitStruct->TMM_Select << 1)) << 4 ;
		*TMM_reg.TMCR[TMM_InitStruct->TMM_Select] = TMM_InitStruct->TMM_CounterClear | TMM_InitStruct->TMM_Clk; //counter cleared condition 
		*TMM_reg.TMGRA = TMM_InitStruct->TMM_CHA_Pulse - 1;			
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_B)== TMM_Channel_B)
		{
			*TMM_reg.TMPMR |=	(TMM_Channel_B >>1) <<(TMM_InitStruct->TMM_Select << 2);
			*TMM_reg.TMGRB = TMM_InitStruct->TMM_CHB_Pulse - 1;	
			*TMM_reg.TMOER1 &= ~((TMM_Channel_B) << (TMM_InitStruct->TMM_Select << 2));
			*TMM_reg.TMPOCR[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_PWM.TMM_CHB.TMM_PWMActiveLevel;
			*TMM_reg.TMOCR |= ((TMM_InitStruct->TMM_PWM.TMM_CHB.TMM_PWMInitLevel << 1) << (TMM_InitStruct->TMM_Select << 2));
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_C)== TMM_Channel_C)
		{
			*TMM_reg.TMPMR |=	(TMM_Channel_C >>1) <<(TMM_InitStruct->TMM_Select << 2);
			*TMM_reg.TMGRC = TMM_InitStruct->TMM_CHC_Pulse - 1;	
			*TMM_reg.TMOER1 &= ~((TMM_Channel_C) << (TMM_InitStruct->TMM_Select << 2));
			*TMM_reg.TMPOCR[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_PWM.TMM_CHC.TMM_PWMActiveLevel << 1;
			*TMM_reg.TMOCR |= ((TMM_InitStruct->TMM_PWM.TMM_CHC.TMM_PWMInitLevel << 2) << (TMM_InitStruct->TMM_Select << 2));
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_D)== TMM_Channel_D)
		{
			*TMM_reg.TMPMR |=	(TMM_Channel_D >>1) <<(TMM_InitStruct->TMM_Select << 2);
			*TMM_reg.TMGRD = TMM_InitStruct->TMM_CHD_Pulse - 1;	
			*TMM_reg.TMOER1 &= ~((TMM_Channel_D) << (TMM_InitStruct->TMM_Select << 2));
			*TMM_reg.TMPOCR[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_PWM.TMM_CHD.TMM_PWMActiveLevel <<  2;
			*TMM_reg.TMOCR |= ((TMM_InitStruct->TMM_PWM.TMM_CHD.TMM_PWMInitLevel << 3) << (TMM_InitStruct->TMM_Select << 2));
		}
		if(TMM_InitStruct->TMM_Mode == TMM_Mode_PWM_RSTSYN)
		{
			*TMM_reg.TMFCR |= 0x01;
		}		
	}
	if(TMM_InitStruct->TMM_Mode == TMM_Mode_CompPWM)
	{
		CGC_PER1PeriphClockCmd(CGC_PER1Periph_PWMCUTOFF,ENABLE);
		*TMM_reg.TMMR |= _80_TMM_TMGRD1_BUFFER |_40_TMM_TMGRC1_BUFFER|_20_TMM_TMGRD0_BUFFER; //the TMGRD1 used as TMGRB1 buffer register??TMGRC1 used as TMGRA1 buffer register?? TMGRD0 are used TMGRB0 buffer register	
		*TMM_reg.TMCR[TMM_InitStruct->TMM_Select] = TMM_InitStruct->TMM_CounterClear | TMM_InitStruct->TMM_Clk; //counter cleared condition 
		*TMM_reg.TMFCR |= (TMM_InitStruct->TMM_BDTR.TMM_NegativeState << 3) | (TMM_InitStruct->TMM_BDTR.TMM_PostiveState << 2)| TMM_InitStruct->TMM_Combine_TransMode;
		
		*TMM_reg.TMDF[TMM_InitStruct->TMM_Select] |= (TMM_InitStruct->TMM_BDTR.TMIOA_BreakPolarity << 6) |(TMM_InitStruct->TMM_BDTR.TMIOB_BreakPolarity << 4)  \
													| (TMM_InitStruct->TMM_BDTR.TMIOC_BreakPolarity << 2) |(TMM_InitStruct->TMM_BDTR.TMIOD_BreakPolarity << 0);
		
		 TMM->TMELC |= (TMM_InitStruct->TMM_BDTR.TMM_Break <<1) << (TMM_InitStruct->TMM_Select << 4);
		
		TMM->OPCTL0 |= TMM_InitStruct->TMM_BDTR.TMM_Break_Release;

		if((TMM_InitStruct->TMM_Channel & TMM_Channel_A) == TMM_Channel_A)
		{
			if(TMM_InitStruct->TMM_Select == TMM0)
			{
				*TMM_reg.TMGRA = TMM_InitStruct->TMM_CHA_Pulse - 1;	
				*TMM_reg.TMGRA = *TMM_reg.TMGRA + TMM_InitStruct->TMM_BDTR.TMM_DeadTime - 1;
				*TMM_reg.TMOER1 |= TMM_Channel_A << (TMM_InitStruct->TMM_Select << 2);
			}
			else
			{
				*TMM_reg.TMGRA = TMM_InitStruct->TMM_CHA_Pulse - 1;	
				*TMM_reg.TMOER1 &= ~((TMM_Channel_A) << (TMM_InitStruct->TMM_Select << 2));
			}
		}		
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_B)== TMM_Channel_B)
		{
			*TMM_reg.TMGRB = TMM_InitStruct->TMM_CHB_Pulse - 1;	
			*TMM_reg.TMOER1 &= ~((TMM_Channel_B) << (TMM_InitStruct->TMM_Select << 2));
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_C)== TMM_Channel_C)
		{
			*TMM_reg.TMGRC = TMM_InitStruct->TMM_CHC_Pulse - 1;	
			*TMM_reg.TMOER1 &= ~(TMM_Channel_C << (TMM_InitStruct->TMM_Select << 2));
		}
		if((TMM_InitStruct->TMM_Channel & TMM_Channel_D)== TMM_Channel_D)
		{
			*TMM_reg.TMGRD = TMM_InitStruct->TMM_CHD_Pulse - 1;	
			*TMM_reg.TMOER1 &= ~(TMM_Channel_D << (TMM_InitStruct->TMM_Select << 2));
		}
		if(TMM_InitStruct->TMM_Select == TMM0)
		{
			TMM->TM0 = TMM_InitStruct->TMM_BDTR.TMM_DeadTime;
		}
		TMM->TM1 = 0;
	}
	*TMM_reg.TMIER[TMM_InitStruct->TMM_Select] |= TMM_InitStruct->TMM_Intp;

}

/**
  * @brief  This function sets TM0 channel counter.
  * @param  None
  * @retval None
  */
void TMM0_Set_Counter(uint8_t ch,uint16_t value)
{
	if(ch == TMM_Channel_A)
	{
		TMM->TMGRA0	= value - 1;
	}
	else if(ch == TMM_Channel_B)
	{
		TMM->TMGRB0	= value - 1;	
	}
	else if(ch == TMM_Channel_C)
	{
		TMM->TMGRC0	= value - 1;		
	}
	else if(ch == TMM_Channel_D)
	{
		TMM->TMGRD0	= value - 1;			
	}
}

/**
  * @brief  This function sets TM1 channel counter.
  * @param  None
  * @retval None
  */
void TMM1_Set_Counter(uint8_t ch,uint16_t value)
{
	if(ch == TMM_Channel_A)
	{
		TMM->TMGRA1	= value - 1;
	}
	else if(ch == TMM_Channel_B)
	{
		TMM->TMGRB1	= value - 1;	
	}
	else if(ch == TMM_Channel_C)
	{
		TMM->TMGRC1	= value - 1;		
	}
	else if(ch == TMM_Channel_D)
	{
		TMM->TMGRD1	= value - 1;			
	}
}

/**
  * @brief  This function starts TM0 and TM1 counter.
  * @param  None
  * @retval None
  */
void TMM_All_Start(void)
{
    TMM->TMSTR |= _01_TMM_TM0_COUNT_START | _02_TMM_TM1_COUNT_START;
}

/**
  * @brief  This function stops TM0 and TM1 counter.
  * @param  None
  * @retval None
  */
void TMM_All_Stop(void)
{
    TMM->TMSTR &= (uint8_t)~_01_TMM_TM0_COUNT_START;	
    TMM->TMSTR &= (uint8_t)~_02_TMM_TM1_COUNT_START;	
}



/**
  * @brief  This function starts TMM0 counter.
  * @param  match_flag : it indicated whether counter TM0 continues count 
  *			after matching compare register TMGRA0
  *		@arg ENABLE: countine count after matching compare register TMGRA0
  *		@arg DISABLE: stop count after matching compare register TMGRA0
  * @retval None
  */
void TMM0_Start(FunctionalState match_flag)
{
    volatile uint8_t tmsr_dummy;

    tmsr_dummy = TMM->TMSR0; /* read TMSR0 before write 0 */
    TMM->TMSR0 = 0x00U; /* clear TM0 each interrupt request */
	if(match_flag == ENABLE)
	{
		TMM->TMSTR |= _04_TMM_TM0_COUNT_CONTINUES;
	}
	else
	{
		TMM->TMSTR |= _00_TMM_TM0_COUNT_STOP_MATCH;
	}
    TMM->TMSTR |= _01_TMM_TM0_COUNT_START;
}



/**
  * @brief  This function stops TMM0 counter.
  * @param  None
  * @retval None
  */
void TMM0_Stop(void)
{
    volatile uint8_t tmsr_dummy;

    TMM->TMSTR |= _04_TMM_TM0_COUNT_CONTINUES;
    TMM->TMSTR &= (uint8_t)~_01_TMM_TM0_COUNT_START;
    tmsr_dummy = TMM->TMSR0; /* read TMSR0 before write 0 */
    TMM->TMSR0 = 0x00U; /* clear TM0 each interrupt request */
}

/**
  * @brief  This function starts TMM1 counter.
  * @param  match_flag : it indicated whether counter TM0 continues count 
  *			after matching compare register TMGRA0
  *		@arg ENABLE: countine count after matching compare register TMGRA0
  *		@arg DISABLE: stop count after matching compare register TMGRA0
  */
void TMM1_Start(FunctionalState match_flag)
{
    volatile uint8_t tmsr_dummy;

    tmsr_dummy = TMM->TMSR1; /* read TMSR1 before write 0 */
    TMM->TMSR1 = 0x00U; /* clear TM1 each interrupt request */
	if(match_flag == ENABLE)
	{
		TMM->TMSTR |= _08_TMM_TM1_COUNT_CONTINUES;
	}
	else
	{
		TMM->TMSTR |= _00_TMM_TM1_COUNT_STOP_MATCH;
	}

    TMM->TMSTR |= _02_TMM_TM1_COUNT_START;
}

/**
  * @brief  This function stops TMM1 counter.
  * @param  None
  * @retval None
  */
void TMM1_Stop(void)
{
    volatile uint8_t tmsr_dummy;

    TMM->TMSTR |= _08_TMM_TM1_COUNT_CONTINUES;
    TMM->TMSTR &= (uint8_t)~_02_TMM_TM1_COUNT_START;
    tmsr_dummy = TMM->TMSR1; /* read TMSR1 before write 0 */
    TMM->TMSR1 = 0x00U; /* clear TM0 each interrupt request */
}

/**
  * @brief  Checks whether the specified TMM_FLAG flag is set or not.
  * @param  TMMx: TMM peripheral select.
  * @param  TMM_FLAG: specifies the flag to check.
  *          This parameter can be one of the following values,whrer x is 0 or 1:
  *            @arg TMM_FLAG_MATCHA: TMx count matchs with Capture Compare RegisterTMGRA0 
  *            @arg TMM_FLAG_MATCHB: TMx count matchs with Capture Compare RegisterTMGRB0 
  *            @arg TMM_FLAG_MATCHC: TMx count matchs with Capture Compare RegisterTMGRC0 
  *            @arg TMM_FLAG_MATCHD: TMx count matchs with Capture Compare RegisterTMGRD0 
  *            @arg TMM_FLAG_OVFLOW: TMx count overflow flag
  * @retval The new state of UART_FLAG (SET or RESET).
  */
FlagStatus TMM_GetFlagStatus(TMMSelect_TypeDef TMMx, uint8_t TMM_FLAG)
{
	FlagStatus bitstatus = RESET;
	/* Check the parameters */
	assert_param(IS_TMM_FLAG(TMM_FLAG));
	assert_param(IS_TMM_SELECT(TMMx));
	/* Check the parameters */
	if(TMMx == TMM0)
	{
		if ((TMM->TMSR0 & TMM_FLAG) != (uint16_t)RESET)
		{
			bitstatus = SET;
		}
		else
		{
			bitstatus = RESET;
		}
	}
	if(TMMx == TMM1)
	{
		if ((TMM->TMSR1 & TMM_FLAG) != (uint16_t)RESET)
		{
			bitstatus = SET;
		}
		else
		{
			bitstatus = RESET;
		}	
	}

	return bitstatus;
}


uint32_t TMM_GetPulseWidth(TMMSelect_TypeDef TMMx, uint8_t channel)
{
    uint8_t  tmsr_temp;
    uint8_t  tmier_temp;
	int32_t width=0;
	
	/* Check the parameters */	
	assert_param(IS_TMM_SELECT(TMMx));
	
	TMM_RegSetting(TMMx);
	
	tmsr_temp = *TMM_reg.TMSR;
	tmier_temp = *TMM_reg.TMIER[TMMx];
	
	if (INTC_GetPendingIRQ(TMM0_IRQn) == 1)
	{
		INTC_ClearPendingIRQ(TMM0_IRQn); /* clear INTTMA interrupt flag */
	}
	else if(INTC_GetPendingIRQ(TMM1_IRQn) == 1)
	{
		INTC_ClearPendingIRQ(TMM1_IRQn); /* clear INTTMA interrupt flag */
	}
	else 
	{
		return 0;	
	}

    if (TMM_GetFlagStatus(TMMx,TMM_FLAG_OVFLOW) == SET)
    {
		*TMM_reg.TMSR = tmsr_temp & ~TMM_FLAG_OVFLOW;
//        tmm_overflow_count_a += 1UL;
//        tmm_overflow_count_b += 1UL;
    }
	
	if(channel == TMM_Channel_A)
	{
		if (TMM_GetFlagStatus(TMMx,TMM_FLAG_MATCHA) == SET)
		{
			*TMM_reg.TMSR = tmsr_temp & ~TMM_FLAG_MATCHA;
			width = (*TMM_reg.TMGRA - *TMM_reg.TMGRC);
			tmm_overflow_count_a = 0;
			if(width < 0)
			{
				width += 0xffff;
			}
		}
	}
	if(channel == TMM_Channel_B)
	{
		if (TMM_GetFlagStatus(TMMx,TMM_FLAG_MATCHB) == SET)
		{
			*TMM_reg.TMSR = tmsr_temp & ~TMM_FLAG_MATCHB;

			width = (*TMM_reg.TMGRB - *TMM_reg.TMGRD);
			tmm_overflow_count_b = 0;
			if(width < 0)
			{
				width += 0xffff;
			}			
		}
	}
	*TMM_reg.TMIER[TMMx] = tmier_temp;
	
	return width;
}