#include "periph_timer.h"

/**
 * 重置TIMER
 * param：TIMERx:
		#define TIMER0 
		#define TIMER1
		#define TIMER2
		#define TIMER3
		#define TIMER4
		#define TIMER5
		#define TIMER6
		#define TIMER7
 */
void TIMER_DeInit(uint16_t TIMERx)
{
    SYS_CTRL->SYS_RESET |= (1 << (24 + TIMERx));
    SYS_CTRL->SYS_RESET &= (~(1 << (24 + TIMERx)));
	// CLK disable
    *(volatile int *)(0x40000020) &= (~(1<<(8 + TIMERx)));
	if (((*(volatile int *)(0x40000020)) & 0xff00) == 0) *(volatile int *)(0x40000028) &= (~(1<<12));
}

void TIMER_Init(uint16_t TIMERx, TIMER_InitTypeDef* TIMER_InitStruct)
{
	uint32_t tmpreg;
	// CLK Enable
    *(volatile int *)(0x40000020) |= (1<<(8 + TIMERx));
    *(volatile int *)(0x40000028) |= (1<<12);
    // 设置TIMER时钟源
	tmpreg = SYS_CTRL->PWMTT_CLK_SYSSEL;
	tmpreg &= (~(0x3 << (TIMERx * 2)));
	tmpreg |= (TIMER_InitStruct->TIMER_CLKSelect << (TIMERx * 2));
	SYS_CTRL->PWMTT_CLK_SYSSEL = tmpreg;
    //时钟选择为48M时需要配置该寄存器
    if (TIMER_InitStruct->TIMER_CLKSelect == TIMER_CLK_SEL_PLL48M)
    {
		*(volatile uint32_t*)(0x42002000) |= 2;
    }

    //配置TIMERx时钟分频
	tmpreg = SYS_CTRL->PWMTT_CLK_SEL;
	tmpreg &= (~(0xf << (TIMERx * 4)));
	tmpreg |= (TIMER_InitStruct->TIMER_CLKDivide << (TIMERx * 4));
	SYS_CTRL->PWMTT_CLK_SEL = tmpreg;
    
	//配置TIMER模式
	tmpreg = *(volatile uint32_t*)(TIMER_CONTROL_BASE + (TIMERx * 0x14));
	tmpreg &= 0x05;
  	tmpreg |= ((TIMER_InitStruct->TIMER_PWM0N100Cmd << 4) | (TIMER_InitStruct->TIMER_PWMCmd << 3) |
		(TIMER_InitStruct->TIMER_Mode));
    *(volatile uint32_t*)(TIMER_CONTROL_BASE + (TIMERx * 0x14)) = tmpreg;

    *(volatile uint16_t*)(TIMER_LOAD_COUNT_OFFSET_BASE + (TIMERx * 0x14)) = TIMER_InitStruct->TIMER_Loadcount;
    *(volatile uint16_t*)(TIMER_LOAD_COUNT2_BASE + (TIMERx * 0x4)) = TIMER_InitStruct->TIMER_Loadcount2;

}

void TIMER_StructInit(TIMER_InitTypeDef *TIMER_InitStruct)
{
    TIMER_InitStruct->TIMER_Mode = TIMER_MODE_FREE_RUNNING;
    TIMER_InitStruct->TIMER_PWMCmd = DISABLE;
    TIMER_InitStruct->TIMER_PWM0N100Cmd = DISABLE;
    TIMER_InitStruct->TIMER_Loadcount = 0xffff;
    TIMER_InitStruct->TIMER_Loadcount2= 0xffff;
    TIMER_InitStruct->TIMER_CLKSelect = TIMER_CLK_SEL_XTAL24M;
    TIMER_InitStruct->TIMER_CLKDivide = TIMER_CLK_DIVIDE_2;
}

void TIMER_Cmd(uint16_t TIMERx, FunctionalState NewState)
{

	if (NewState != DISABLE)
  	{
    	*(volatile uint8_t*)(TIMER_CONTROL_BASE + (TIMERx) * 0x14) |= ENABLE ;
  	}
  	else
  	{
    	*(volatile uint8_t*)(TIMER_CONTROL_BASE + (TIMERx) * 0x14) &= ~ENABLE ;
  	}	
}
FlagStatus TIMER_GetFlagStatus(uint16_t TIMERx)
{
	FlagStatus flag;
	flag = (TIMER->TIMERS_RAW_INT_STATUS & (1 << TIMERx));
	if(flag != RESET)
	{
		return SET;
	}
	else
	{
		return RESET;
	}
}
uint8_t TIMER_GetAllFlagStatus(void)
{
	return TIMER->TIMERS_RAW_INT_STATUS;
}

void TIMER_ClearFlag(uint16_t TIMERx)
{
	*(volatile uint8_t*)(TIMER_CLR_IT_STATUS_BASE + (TIMERx * 0x14));
}
void TIMER_ClearAllFlag(void)
{
	TIMER->TIMERS_EOI;
}

void TIMER_ITCmd(uint16_t TIMERx, FunctionalState NewState)
{
	if (NewState != DISABLE)
  	{
    	*(volatile uint8_t*)(TIMER_CONTROL_BASE + (TIMERx * 0x14)) &= ~(ENABLE << 2);
  	}
  	else
  	{
    	*(volatile uint8_t*)(TIMER_CONTROL_BASE + (TIMERx * 0x14)) |= (ENABLE << 2) ;
    }
}

ITStatus TIMER_GetITStatus (uint16_t TIMERx)
{
	return *(volatile uint8_t*)(TIMER_IT_STATUS_BASE + (TIMERx * 0x14));
}

uint8_t TIMER_GetAllITStatus(void)
{
	return TIMER->TIMERS_INT_STATUS;
}

void TIMER_ClearITPendingBit(uint16_t TIMERx)
{
	*(volatile uint8_t*)(TIMER_CLR_IT_STATUS_BASE + (TIMERx * 0x14));
}

void TIMER_ClearAllITPendingBit(void)
{
	TIMER->TIMERS_EOI;
}

/**
 * 
 * 
 */
void TIMER_SetLoadCount(uint16_t TIMERx, uint16_t LoadCount, uint16_t LoadCount2)
{
	*(volatile uint16_t*)(TIMER_LOAD_COUNT_OFFSET_BASE+ (TIMERx * 0x14)) = LoadCount;
	*(volatile uint16_t*)(TIMER_LOAD_COUNT2_BASE + (TIMERx * 0x4)) = LoadCount2;
}





