/*Copyright (C), 2024-2030
*文件名:	USER.c
*版  本:	Ver1.00
*日  期:	2025/04/30
*描  述:	常用函数定义
*备  注:     
**********************************************************/
#include "USER.h"
#include "BL51F003T.h"	
#include "Uart.h"
#include "stdio.h"
/**********************************************************/

/**
	* @brief  使能PWMn
  * @param  num: PWM0-PWM7
  * @retval None
	*/
void pwm_enable(PWM_NUM_ENUM num)
{
	PWMEN |= (0x01<<num);
}

/**
	* @brief  关闭PWMn
  * @param  num: PWM0-PWM7
  * @retval None
	*/
void pwm_disable(PWM_NUM_ENUM num)
{
	PWMEN &= (~(0x01<<num));
}

/**
	* @brief  使能PWMn的中断
  * @param  num: PWM0-PWM7
  * @retval None
	*/
void pwm_ie_enable(PWM_NUM_ENUM num)
{
	PWMIE |= (0x01<<num);
}

/**
	* @brief  关闭PWMn的中断
  * @param  num: PWM0-PWM7
  * @retval None
	*/
void pwm_ie_disable(PWM_NUM_ENUM num)
{
	PWMIE &= (~(0x01<<num));
}

/**
	* @brief  读取PWMn的中断标志
  * @param  num: PWM0-PWM7
  * @retval None
	*/
char pwm_get_flag(PWM_NUM_ENUM num)
{
	return PWMFLG&(0x01<<num);
}	


/**
	* @brief  设置PWMn的时钟源
  * @param  num: PWM0-PWM7
	*         clk: 时钟源
  * @retval None
	*/
void pwm_set_source_clk(PWM_NUM_ENUM num, PWM_CLK_ENUM clk )
{
	PWM_N_ENUM n;
	
	if((clk<0)||(clk>3))
	{
		/* error : out of range */
		return;
	}
	
	if((num == PWM0)||(num == PWM1))
	{
		n = PWM0_1;
	}
	else if((num == PWM2)||(num == PWM3))
	{
		n = PWM2_3; 
	}
	else if((num == PWM4)||(num == PWM5))
	{
		n = PWM4_5;
	}

	
	//pwm_set_index(n);
	if((num == PWM0)||(num == PWM1))
	{
		PWM0CFG &= 0xFC;
		PWM0CFG |= clk;
	}
	if((num == PWM2)||(num == PWM3))
	{
		PWM2CFG &= 0xFC;
		PWM2CFG |= clk;
	}
}

/**
	* @brief  设置PWMn的预分频
  * @param  num: PWM0-PWM7
	*         pdiv: 预分频值(0-15)
  * @retval None
	*/
void pwm_pdiv(PWM_NUM_ENUM num, char pdiv)
{
	PWM_N_ENUM n;
	
	if((pdiv<0)||(pdiv>15))
	{
		/* error : out of range */
		return;
	}
	
	if((num == PWM0)||(num == PWM1))
	{
		n = PWM0_1;
		PWM0PDIV = pdiv;
	}
	else if((num == PWM2)||(num == PWM3))
	{
		n = PWM2_3;
		PWM2PDIV = pdiv;		
	}
}

/**
	* @brief  设置PWMn的输出模式
  * @param  num: PWM0-PWM7
	*         mode: 输出模式(独立/互补)
  * @retval None
	*/
void pwm_set_out_mode(PWM_NUM_ENUM num, PWM_MODE_ENUM mode)
{
	PWM_N_ENUM n;
	
	if((num == PWM0)||(num == PWM1))
	{
		n = PWM0_1;
	}
	else if((num == PWM2)||(num == PWM3))
	{
		n = PWM2_3;
	}
	else if((num == PWM4)||(num == PWM5))
	{
		n = PWM4_5;
	}

	//pwm_set_index(n);
	
	if(mode == PWM_MODE_INDP)
	{
		if(num == PWM0)
		{
			PWM0CFG &= 0xF7;
		}
		if(num == PWM2)
		{
			PWM2CFG &= 0xF7;
		}
	}
	else if(mode == PWM_MODE_COMP)
	{
		if(num == PWM0)
		{
			PWM0CFG |= 0x08; 
		}
		if(num == PWM2)
		{
			PWM2CFG |= 0x08; 
		}
	}
}

/**
	* @brief  设置PWMn的分频
  * @param  num: PWM0-PWM7
	*         div: 分频值(0-4095)
  * @retval None
	*/
void pwm_set_div(PWM_NUM_ENUM num, int div)
{
	if((div<0) || (div>4095))
	{
		/* out of range */
		return;
	}
	
	//pwm_set_index(num);
	if(num == PWM0)
	{
		PWM0DIVH = (div>>8)&0xFF;
		PWM0DIVL = div&0xFF;
	}
	if(num == PWM1)
	{	
		PWM1DIVH = (div>>8)&0xFF;
		PWM1DIVL = div&0xFF;
	}
	if(num == PWM2)
	{	
		PWM2DIV = div&0xFF;
	}
	if(num == PWM3)
	{	
		PWM3DIV = div&0xFF;
	}
	if(num == PWM4)
	{
		PWM4DIVH = (div>>8)&0xFF;
		PWM4DIVL = div&0xFF;
	}
	if(num == PWM5)
	{	
		PWM5DIVH = (div>>8)&0xFF;
		PWM5DIVL = div&0xFF;
	}
}

/**
	* @brief  设置PWMn的占空比
  * @param  num: PWM0-PWM7
	*         duty: duty值(0-4095)
  * @retval None
	*/
void pwm_set_duty(PWM_NUM_ENUM num, int duty)
{
	if((duty<0) || (duty>4095))
	{
		/* out of range */
		return;
	}
	
	//pwm_set_index(num);
	if(num == PWM0)
	{
		PWM0DUTH = (duty>>8)&0xFF;
		PWM0DUTL = duty&0xFF;
	}
	if(num == PWM1)
	{
		PWM1DUTH = (duty>>8)&0xFF;
		PWM1DUTL = duty&0xFF;
	}
	if(num == PWM2)
	{
		PWM2DUT = duty&0xFF;
	}
	if(num == PWM3)
	{
		PWM3DUT = duty&0xFF;
	}
	if(num == PWM4)
	{
		PWM4DUTH = (duty>>8)&0xFF;
		PWM4DUTL = duty&0xFF;
	}
	if(num == PWM5)
	{
		PWM5DUTH = (duty>>8)&0xFF;
		PWM5DUTL = duty&0xFF;
	}
}

/**
	* @brief  设置PWMn的死区时间(仅用在互补输出模式)
  * @param  num: PWM1/PWM3/PWM5/PWM7
	*         dt: duty值(0-255)
  * @retval None
	*/
void pwm_set_dt(PWM_NUM_ENUM num, int dt)
{
	if((dt<0) || (dt>255))
	{
		/* out of range */
		return;
	}	
	if(num == PWM1)
	{
		PWM1DUTL = dt;
		return;
	}
	if(num == PWM3)
	{	
		PWM3DUT = dt;	
		return;
	}
}
/**
	* @brief  1. 打开PWM2，从P02输出250HZ的PWM作为测试信号。
	*					2. 打开PWM0和PWM1，P01作为抓取输入口，抓取从P02输出。
  * @param  None
  * @retval None
	*/
void PWM_INIT()
{
	P00_FUN_PWM0;														//P00配置为PWM功能
	P01_FUN_PWM1;														//P01配置为PWM功能
	pwm_pdiv(PWM0,0);												//设置预分频0分频
	pwm_set_div(PWM0, 4095);								//设置PWM0的分频
	pwm_set_duty(PWM0, 512);								//设置PWM0的占空比为DUT/(DIV+1)
	pwm_set_source_clk(PWM0, PWM_CLK_LRC);	//设置PWM0的时钟源为LRC

	/* 双沿抓取模式 */
	//SET_BIT(PWM0CFG, 7);
	//SET_BIT(PWM0CFG, 6);

	/* 上沿抓取模式 */
	CLR_BIT(PWM0CFG, 7);
	SET_BIT(PWM0CFG, 6);
	
	/* 下沿抓取模式 */ 
	// SET_BIT(PWM0CFG, 7);
	// CLR_BIT(PWM0CFG, 6);
	
	pwm_enable(PWM0);												//使能PWM0
	pwm_ie_enable(PWM0);										//PWM0中断使能
	pwm_enable(PWM1);												//使能PWM1
	pwm_ie_enable(PWM1);										//PWM1中断使能
	
	/*抓取模式选择*/
#ifdef __CLR_MODE__
	pwm_set_out_mode(PWM0, PWM_MODE_COMP);
#else
	pwm_set_out_mode(PWM0, PWM_MODE_INDP);	
#endif	

	/* 测试信号PWM2，作为触发信号，250HZ */
	P02_FUN_PWM2;													//配置P02为PWM功能
	pwm_set_out_mode(PWM2, PWM_MODE_INDP);//设置PWM2独立输出
	pwm_pdiv(PWM2,0);										  //不分频
	pwm_set_div(PWM2, 127); 								//设置PWM2的分频,输出波形频率为时钟源/(31+1) = 32K/32=1K
	pwm_set_duty(PWM2, 64);								//设置PWM2的占空比为DUT/(DIV+1)
	pwm_set_source_clk(PWM2, PWM_CLK_LRC);//设置PWM2的时钟源为LRC
	pwm_enable(PWM2);											//使能PWM2
	
	INT_PWM;																//PWM中断使能
}
/**
	* @brief  PWM抓取中断，uart打印抓取结果
  * @param  None
  * @retval None
	*/
void pwm_isr() interrupt 4
{
	INT16S dut;
	static INT16S dut_inc = 0;
	static INT16S last;
	INT16S ret;
	
	/* PWM0 计满溢出 */
	if(PWMFLG & 0x01)
	{
		dut_inc += 4096; 
		PWMFLG &= 0xFE;
	}
	
	if(PWMFLG & 0x02)
	{
		dut = ((PWM0DUTH&0x0f)<<8) | PWM0DUTL;
		ret = dut_inc + dut - last;
		
#ifdef __CLR_MODE__
		printf("\nI diff: \t%d, \t%bx, \t%bx, \t%bx",dut, PWM0DUTH, PWM0DUTL, PWMFLG);
	
#else
		printf("\nI %d\t%d\t%d\t%bd",dut_inc + dut - last, dut, last, PWMFLG);
		printf("\nI");
#endif
		
		last = dut;
		dut_inc = 0;
		PWMFLG &= 0xFD;
	}
}