/*********************************************************
*Copyright (C), 2024-2030
*文件名:	USER.c
*版  本:	Ver1.00
*日  期:	2025/08/04
*描  述:	灯带功能函数、变量定义
*备  注:	
**********************************************************/
#include "USER.h"
#include "BL51F003T.h"	

xdata INT8U LED_DATA_BUF[100][3] = {0};
LED_Strip LED_0;
LED_Strip LED_1;

// 使用粗延时让时序拉低80us以上
void LED_RESET(void)
{
	int i;
	for(i=0; i<180; i++);
}

/**
	* @brief  1.PWM5配置为RGB灯带功能，
						PWM4CFG的bit0、bit1对应LED 显示 1 时间设置
						00：PWM 输出占空比为（PWMnDIV - PWMnDUT）/（PWMnDIV + 1）
						01：PWM 输出占空比为（2 * PWMnDUT）/（PWMnDIV + 1）
						10：PWM 输出占空比为（3 * PWMnDUT）/（PWMnDIV + 1）
						11：PWM 输出占空比为（4 * PWMnDUT）/（PWMnDIV + 1）
  * @param  None
  * @retval
	*/
void USER_PWM_INIT_RGB(void)
{
	/* 灯带功能 */
#if (IS_PWM4_ACTIVE)
	
	P04_FUN_PWM4;										//配置P04为PWM功能
	PWM4CFG = 0x40|0x00;						//PWM4选择灯带模式
	pwm_set_div(PWM4, 24); 					//设置PWM4
	pwm_set_duty(PWM4, 8);					//设置PWM4
	pwm_enable(PWM4);								//使能PWM4
	pwm_ie_enable(PWM4);						//中断使能PWM4
	INT_PWM;												//开启PWM中断
	LEDBTC = 0x07;									//LED0数据有效位配置，选择8位
	
#elif (IS_PWM5_ACTIVE)
	
	P05_FUN_PWM5;										//配置P05为PWM功能
	PWM4CFG = 0x80|0x00;						//PWM5选择灯带模式
	pwm_set_div(PWM5, 24); 					//设置PWM5
	pwm_set_duty(PWM5, 8);					//设置PWM5
	pwm_enable(PWM5);								//使能PWM5
	pwm_ie_enable(PWM5);						//中断使能PWM5
	INT_PWM;												//开启PWM中断
	LEDBTC = 0x70;									//LED1数据有效位配置，选择8位
	
#endif
}

/**
	* @brief  PWM 中断
  * @param  None
  * @retval None
**/	
void pwm_isr() interrupt 4
{
#if (IS_PWM4_ACTIVE)
	
	if(PWMFLG & 0x10)	// PWM5数据填写完成中断标志
	{		
		PWMFLG &= 0xEF;	// 清除中断标志位
		
		if ((LED_0.led_index < LED_0.lit_leds) && \
				(LED_0.led_index < LED_0.total_leds))	// 需要亮起的灯珠
		{
			LEDAT0 = LED_DATA_BUF[LED_0.led_index][LED_0.rgb_flag++];		//PWM5数据更新
			if (LED_0.rgb_flag == 3)	// 判断是否发送完24bit数据
			{
				LED_0.rgb_flag = 0;
				LED_0.led_index++;
			}
		}
		else if (LED_0.led_index < LED_0.total_leds)	// 不需要亮起的灯珠
		{
			LEDAT0 = 0;
			LED_0.rgb_flag++;
			if (LED_0.rgb_flag == 3)
			{
				LED_0.rgb_flag = 0;
				LED_0.led_index++;
			}
		}
		else	// RESET
		{
			LED_RESET();	// 发出RESET信号
			
			if (LED_0.updata_flag == UPD_NONE) // 没有数据更新时，继续显示
			{
				LED_0.led_index = 0;
				LED_0.rgb_flag = 0;
				LEDAT0 = LED_DATA_BUF[LED_0.led_index][LED_0.rgb_flag++];		//PWM5数据更新
			}
		}
	}
	
#elif (IS_PWM5_ACTIVE)
	
	if(PWMFLG & 0x20)	// PWM5数据填写完成中断标志
	{		
		PWMFLG &= 0xDF;	// 清除中断标志位
		
		if ((LED_1.led_index < LED_1.lit_leds) && \
				(LED_1.led_index < LED_1.total_leds))	// 需要亮起的灯珠
		{
			LEDAT1 = LED_DATA_BUF[LED_1.led_index][LED_1.rgb_flag++];		//PWM5数据更新
			if (LED_1.rgb_flag == 3)	// 判断是否发送完24bit数据
			{
				LED_1.rgb_flag = 0;
				LED_1.led_index++;
			}
		}
		else if (LED_1.led_index < LED_1.total_leds)	// 不需要亮起的灯珠
		{
			LEDAT1 = 0;
			LED_1.rgb_flag++;
			if (LED_1.rgb_flag == 3)
			{
				LED_1.rgb_flag = 0;
				LED_1.led_index++;
			}
		}
		else	// RESET
		{
			LED_RESET();	// 发出RESET信号
			
			if (LED_1.updata_flag == UPD_NONE) // 没有数据更新时，继续显示
			{
				LED_1.led_index = 0;
				LED_1.rgb_flag = 0;
				LEDAT1 = LED_DATA_BUF[LED_1.led_index][LED_1.rgb_flag++];		//PWM5数据更新
			}
		}
	}
	
#endif
}

/**
	* @brief  灯带结构体成员初始化
  * @param  None
  * @retval None
**/	
void USER_LED_INIT(void)
{
#if (IS_PWM4_ACTIVE)
	
	LED_0.total_leds = LED_NUM_MAX;
	LED_0.lit_leds = LED_NUM_MAX;
	LED_0.led_index = 0;
	LED_0.rgb_flag = 0;
	LED_0.updata_flag = UPD_NONE;	
	
#elif (IS_PWM5_ACTIVE)
	
	LED_1.total_leds = LED_NUM_MAX;
	LED_1.lit_leds = LED_NUM_MAX;
	LED_1.led_index = 0;
	LED_1.rgb_flag = 0;
	LED_1.updata_flag = UPD_NONE;	
	
#endif
}

/**
	* @brief  装填PWM数据，开始灯带显示
  * @param  None
  * @retval None
**/	
void User_SET_LED(void)
{
#if (IS_PWM4_ACTIVE)
	
	while(LED_0.rgb_flag == 3);		// 等待发送完24bit的RGB数据
	LED_0.rgb_flag = 0;
	LED_0.led_index = 0;
	LED_0.updata_flag = UPD_NONE;			// 灯带数据更新完成
	LEDAT0 = LED_DATA_BUF[LED_0.led_index][LED_0.rgb_flag++];		//开始更新PWM5数据

#elif (IS_PWM5_ACTIVE)
	
	while(LED_1.rgb_flag == 3);		// 等待发送完24bit的RGB数据
	LED_1.rgb_flag = 0;
	LED_1.led_index = 0;
	LED_1.updata_flag = UPD_NONE;			// 灯带数据更新完成
	LEDAT1 = LED_DATA_BUF[LED_1.led_index][LED_1.rgb_flag++];		//开始更新PWM5数据

#endif
}

/**
	* @brief  灯带显示测试1，效果为亮起指定数量指定颜色的灯珠
  * @param  r：红色灰度0~255
						g：绿色灰度0~255
						b：蓝色灰度0~255
						lit_num：要点亮灯珠的数量
  * @retval None
**/	
void USER_SET_LEDBUF_TEXT_1(INT8U r, INT8U g, INT8U b, INT16U lit_num)
{
	INT16U i,j;
#if (IS_PWM4_ACTIVE)
	if (lit_num > LED_0.total_leds)
	{
		LED_0.lit_leds = LED_0.total_leds;
	}
	else
	{
		LED_0.lit_leds = lit_num;
	}
	
	LED_0.updata_flag = UPD_ONGOING;	// 灯带数据更新中
	for (i=0; i<LED_0.lit_leds; i++)	
	{	// 具体赋值顺序以实际灯带为准
		LED_DATA_BUF[i][0] = g;			
		LED_DATA_BUF[i][1] = r;			
		LED_DATA_BUF[i][2] = b;		
	}
	for (j=i; j<LED_0.total_leds; j++)
	{
		LED_DATA_BUF[j][0] = 0;
		LED_DATA_BUF[j][1] = 0;
		LED_DATA_BUF[j][2] = 0;
	}
	
	User_SET_LED();
#elif (IS_PWM5_ACTIVE)
	if (lit_num > LED_1.total_leds)
	{
		LED_1.lit_leds = LED_1.total_leds;
	}
	else
	{
		LED_1.lit_leds = lit_num;
	}
	
	LED_1.updata_flag = UPD_ONGOING;	// 灯带数据更新中
	for (i=0; i<LED_1.lit_leds; i++)	
	{	// 具体赋值顺序以实际灯带为准
		LED_DATA_BUF[i][0] = g;			
		LED_DATA_BUF[i][1] = r;			
		LED_DATA_BUF[i][2] = b;		
	}
	for (j=i; j<LED_1.total_leds; j++)
	{
		LED_DATA_BUF[j][0] = 0;
		LED_DATA_BUF[j][1] = 0;
		LED_DATA_BUF[j][2] = 0;
	}
	
	User_SET_LED();
#endif
}

/**
	* @brief  灯带显示测试2，效果为流水灯
  * @param  r：红色灰度0~255
						g：绿色灰度0~255
						b：蓝色灰度0~255
						lit_num：要点亮灯珠的数量
  * @retval None
**/	
void USER_SET_LEDBUF_TEXT_2(INT8U r, INT8U g, INT8U b)
{
	INT16U i,j;
#if (IS_PWM4_ACTIVE)
	
	while(LED_0.led_index == LED_0.total_leds);	// 等待上一组数据显示完
	
	LED_0.updata_flag = UPD_ONGOING;	// 灯带数据更新中
	for (i=0; i<LED_0.total_leds; i++)	
	{
		for (j=0; j<LED_0.total_leds; j++)
		{
			if (j <= i)
			{	// 具体赋值顺序以实际灯带为准
				LED_DATA_BUF[j][0] = g;
				LED_DATA_BUF[j][1] = r;
				LED_DATA_BUF[j][2] = b;
			}
			else
			{
				LED_DATA_BUF[j][0] = 0;
				LED_DATA_BUF[j][1] = 0;
				LED_DATA_BUF[j][2] = 0;
			}
		}
	
		User_SET_LED();	
		delay_ms(10);
	}
	
#elif (IS_PWM5_ACTIVE)
	
	while(LED_1.led_index == LED_1.total_leds);	// 等待上一组数据显示完
	
	LED_1.updata_flag = UPD_ONGOING;	// 灯带数据更新中
	for (i=0; i<LED_1.total_leds; i++)	
	{
		for (j=0; j<LED_1.total_leds; j++)
		{
			if (j <= i)
			{	// 具体赋值顺序以实际灯带为准
				LED_DATA_BUF[j][0] = g;
				LED_DATA_BUF[j][1] = r;
				LED_DATA_BUF[j][2] = b;
			}
			else
			{
				LED_DATA_BUF[j][0] = 0;
				LED_DATA_BUF[j][1] = 0;
				LED_DATA_BUF[j][2] = 0;
			}
		}
	
		User_SET_LED();	
		delay_ms(10);
	}
	
#endif
}


