#include "includes.h"

PWM_CONTROL_T g_pwm;
PWM_AUTO_ADJUST_T g_pwmAutoAdj;

void PWM_Init(void){
	U32_T temp_val = 0;
	memset(&g_pwm,0,sizeof(PWM_CONTROL_T));
	memset(&g_pwmAutoAdj,0,sizeof(PWM_AUTO_ADJUST_T));
	
	g_pwm.allBrightness = g_eeprom.allBrightness;
	g_pwm.switchState[PWM_OUT_CH1] = g_eeprom.swithcState[PWM_OUT_CH1];
	g_pwm.switchState[PWM_OUT_CH2] = g_eeprom.swithcState[PWM_OUT_CH2];
	g_pwm.switchState[PWM_OUT_CH3] = g_eeprom.swithcState[PWM_OUT_CH3];
	g_pwm.switchState[PWM_OUT_CH4] = g_eeprom.swithcState[PWM_OUT_CH4];
	
	g_pwm.gradualTime[PWM_OUT_CH1] = g_eeprom.gradialTime[PWM_OUT_CH1];
	g_pwm.gradualTime[PWM_OUT_CH2] = g_eeprom.gradialTime[PWM_OUT_CH2];
	g_pwm.gradualTime[PWM_OUT_CH3] = g_eeprom.gradialTime[PWM_OUT_CH3];
	g_pwm.gradualTime[PWM_OUT_CH4] = g_eeprom.gradialTime[PWM_OUT_CH4];
	
	g_pwm.irqEnable = TRUE;
	g_pwm.allBrightnessUpLimit = g_eeprom.allBrightnessUpLimit;
    g_pwm.allBrightnessDownLimit = g_eeprom.allBrightnessDownLimit;
	temp_val = (U32_T)((PWM_OUT_VAL_MAX * g_pwm.allBrightness * g_pwm.allBrightnessUpLimit))/10000;
	g_pwm.allPwmUpLimit = temp_val;
	temp_val = (U32_T)((PWM_OUT_VAL_MAX * g_pwm.allBrightness * g_pwm.allBrightnessDownLimit))/10000;
	g_pwm.allPwmDownLimit = temp_val;
	
	PWM_SetOutBrightness(PWM_OUT_CH1,g_eeprom.brightness[PWM_OUT_CH1]);
	PWM_SetOutBrightness(PWM_OUT_CH2,g_eeprom.brightness[PWM_OUT_CH2]);
	PWM_SetOutBrightness(PWM_OUT_CH3,g_eeprom.brightness[PWM_OUT_CH3]);
	PWM_SetOutBrightness(PWM_OUT_CH4,g_eeprom.brightness[PWM_OUT_CH4]);
	
	Dbg_Println(DBG_BIT_SYS_STATUS,"allBrightness %d",g_pwm.allBrightness);
	Dbg_Println(DBG_BIT_SYS_STATUS,"allBrightnessUpLimit %d",g_pwm.allBrightnessUpLimit);
	Dbg_Println(DBG_BIT_SYS_STATUS,"allBrightnessDownLimit %d",g_pwm.allBrightnessDownLimit);
	Dbg_Println(DBG_BIT_SYS_STATUS,"allBrightness %d",g_pwm.allBrightness);
	Dbg_Println(DBG_BIT_SYS_STATUS,"switchState[PWM_OUT_CH1] %d",g_pwm.switchState[PWM_OUT_CH1]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"switchState[PWM_OUT_CH2] %d",g_pwm.switchState[PWM_OUT_CH2]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"switchState[PWM_OUT_CH3] %d",g_pwm.switchState[PWM_OUT_CH3]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"switchState[PWM_OUT_CH4] %d",g_pwm.switchState[PWM_OUT_CH4]);
	
	Dbg_Println(DBG_BIT_SYS_STATUS,"gradualTime[PWM_OUT_CH1] %d",g_pwm.gradualTime[PWM_OUT_CH1]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"gradualTime[PWM_OUT_CH2] %d",g_pwm.gradualTime[PWM_OUT_CH2]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"gradualTime[PWM_OUT_CH3] %d",g_pwm.gradualTime[PWM_OUT_CH3]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"gradualTime[PWM_OUT_CH4] %d",g_pwm.gradualTime[PWM_OUT_CH4]);
	
	Dbg_Println(DBG_BIT_SYS_STATUS,"brightness[PWM_OUT_CH1] %d",g_eeprom.brightness[PWM_OUT_CH1]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"brightness[PWM_OUT_CH2] %d",g_eeprom.brightness[PWM_OUT_CH2]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"brightness[PWM_OUT_CH3] %d",g_eeprom.brightness[PWM_OUT_CH3]);
	Dbg_Println(DBG_BIT_SYS_STATUS,"brightness[PWM_OUT_CH4] %d",g_eeprom.brightness[PWM_OUT_CH4]);
	
	//设置指定亮度
//	g_pwm.pwmValCurr[PWM_OUT_CH1] = 0;
//	g_pwm.pwmValCurr[PWM_OUT_CH2] = 550;
//	g_pwm.pwmValCurr[PWM_OUT_CH3] = 600;
//	g_pwm.pwmValCurr[PWM_OUT_CH4] = 650;
//	
//	PWM_SetOutDuty(PWM_OUT_CH1,g_pwm.pwmValCurr[PWM_OUT_CH1]);
//	PWM_SetOutDuty(PWM_OUT_CH2,g_pwm.pwmValCurr[PWM_OUT_CH2]);
//	PWM_SetOutDuty(PWM_OUT_CH3,g_pwm.pwmValCurr[PWM_OUT_CH3]);
//	PWM_SetOutDuty(PWM_OUT_CH4,g_pwm.pwmValCurr[PWM_OUT_CH4]);
	
	//循环调光测试
//	PWM_SetAutoAdjust(PWM_OUT_CH1,0x01,0x01,2000);
//	PWM_SetAutoAdjust(PWM_OUT_CH2,0x01,0x01,4000);
//	PWM_SetAutoAdjust(PWM_OUT_CH3,0x01,0x01,8000);
//	PWM_SetAutoAdjust(PWM_OUT_CH4,0x01,0x01,12000);
}

/*********************************************************************
 * @fn      PWM_SetOutDuty
 * @brief   设置PWM通道输出亮度
 * @para  	
 * 		index:		设置通道 	0~3
 * 		val:		输出值	 	PWM_OUT_VAL_MIN ~ PWM_OUT_VAL_MAX
 */
void PWM_SetOutDuty(U8_T index,U16_T val){
	U16_T temp_val = 0;
	if(val > PWM_OUT_VAL_MAX) return;
	
	//temp_val = PWM_OUT_VAL_MAX - val;	
	temp_val = val;
	switch(index){
		case PWM_OUT_CH1:
			EPT0->CMPA=temp_val;
			break;
		case PWM_OUT_CH2:
			EPT0->CMPB=temp_val;
			break;
		case PWM_OUT_CH3:
			EPT0->CMPC=temp_val;
			break;
		case PWM_OUT_CH4:
			EPT0->CMPD=temp_val;
			break;
	}
}

/*********************************************************************
 * @fn      PWM_SetCHGradualTime
 * @brief   设置PWM通道渐变时间
 * @para  	
 * 		index:		设置通道 	0~3
 * 		val:		渐变时间 	单位：ms 
 */
void PWM_SetCHGradualTime(U8_T index, U16_T val){
	if(index >= PWM_OUT_CH_MAX) return ;
	
	g_pwm.gradualTime[index] = val;
}

/*********************************************************************
 * @fn      PWM_SetDownLimitVal
 * @brief   设置PWM调光上限
 * @para  	
 * 		val:		上限百分比 	0~100
 */
void PWM_SetUpLimitVal(U8_T val)
{
	U32_T temp_val = 0;
	
    g_pwm.allBrightnessUpLimit = val;
	temp_val = (U32_T)((PWM_OUT_VAL_MAX * g_pwm.allBrightness * g_pwm.allBrightnessUpLimit))/10000;
    g_pwm.allPwmUpLimit = temp_val;
    
    PWM_SetOutBrightness(PWM_OUT_CH1, g_pwm.brightnessCurr[PWM_OUT_CH1]);
    PWM_SetOutBrightness(PWM_OUT_CH2, g_pwm.brightnessCurr[PWM_OUT_CH2]);
    PWM_SetOutBrightness(PWM_OUT_CH3, g_pwm.brightnessCurr[PWM_OUT_CH3]);
    PWM_SetOutBrightness(PWM_OUT_CH4, g_pwm.brightnessCurr[PWM_OUT_CH4]);
}

/*********************************************************************
 * @fn      PWM_SetDownLimitVal
 * @brief   设置PWM调光下限
 * @para  	
 * 		val:		下限百分比 	0~100
 */
void PWM_SetDownLimitVal(U8_T val)
{
	U32_T temp_val = 0;
	
    g_pwm.allBrightnessDownLimit = val;
	temp_val = (U32_T)((PWM_OUT_VAL_MAX * g_pwm.allBrightness * g_pwm.allBrightnessDownLimit))/10000;
    g_pwm.allPwmDownLimit = temp_val;
    
    PWM_SetOutBrightness(PWM_OUT_CH1, g_pwm.brightnessCurr[PWM_OUT_CH1]);
    PWM_SetOutBrightness(PWM_OUT_CH2, g_pwm.brightnessCurr[PWM_OUT_CH2]);
    PWM_SetOutBrightness(PWM_OUT_CH3, g_pwm.brightnessCurr[PWM_OUT_CH3]);
    PWM_SetOutBrightness(PWM_OUT_CH4, g_pwm.brightnessCurr[PWM_OUT_CH4]);
}

/*********************************************************************
 * @fn      Pwm_SetOnOffState
 * @brief   设置PWM通道开关状态
 * @para  	
 * 		index:		设置通道 	0~3
 * 		state:	设置开关状态	0x00:关；0x01:开
 */
void Pwm_SetOnOffState(U8_T index, U8_T state)
{
	if(index >= PWM_OUT_CH_MAX) return ;
	
    g_pwm.switchState[index] = state;
    PWM_SetOutBrightness(index, g_pwm.brightnessCurr[index]);
}

/*********************************************************************
 * @fn      Pwm_SetAllBrightness
 * @brief   设置PWM全局亮度
 * @para  	
 * 		val:		设置全局亮度 	0~100
 */
void Pwm_SetAllBrightness(U8_T val)
{
    g_pwm.allBrightness = val;
    PWM_SetOutBrightness(PWM_OUT_CH1, g_pwm.brightnessCurr[PWM_OUT_CH1]);
    PWM_SetOutBrightness(PWM_OUT_CH2, g_pwm.brightnessCurr[PWM_OUT_CH2]);
    PWM_SetOutBrightness(PWM_OUT_CH3, g_pwm.brightnessCurr[PWM_OUT_CH3]);
    PWM_SetOutBrightness(PWM_OUT_CH4, g_pwm.brightnessCurr[PWM_OUT_CH4]);
}

/*********************************************************************
 * @fn      PWM_SetOutBrightness
 * @brief   设置PWM 通道输出亮度
 * @para  	
 * 		index:		设置通道 	0~3
 * 		brightness：设置亮度	0~100
 */
void PWM_SetOutBrightness(U8_T index, U8_T brightness){
	U32_T tempPwmVal = 0;
	
	if(brightness != 0x00){
		if(brightness >= g_pwm.allBrightnessUpLimit) {
			brightness = g_pwm.allBrightnessUpLimit;
		}else if(brightness <= g_pwm.allBrightnessDownLimit){
			brightness = g_pwm.allBrightnessDownLimit;
		}
	}
	
	g_pwm.irqEnable = FALSE;
	
	g_pwmAutoAdj.enable[index] = FALSE;
	g_pwm.controlFlag[index] = TRUE;
	g_pwm.brightnessCurr[index] = brightness;
	//当前PWM值 = PWM调节最大值 * 全局亮度百分比 * 当前亮度百分比 * 开关状态
	tempPwmVal = ((PWM_OUT_VAL_MAX * g_pwm.allBrightness * g_pwm.brightnessCurr[index]) * g_pwm.switchState[index])/10000;
	g_pwm.pwmValTarget[index] = tempPwmVal;
	
	if(g_pwm.pwmValTarget[index] == g_pwm.pwmValCurr[index]){
		g_pwm.addOrDecFlag[index] = PWMA_Nochange;
	}else if(g_pwm.pwmValTarget[index] > g_pwm.pwmValCurr[index]){
		g_pwm.addOrDecFlag[index] = PWMA_Ascending;
		
		if(g_pwm.gradualTime[index] != 0x00){
			tempPwmVal = g_pwm.pwmValTarget[index] - g_pwm.pwmValCurr[index];
			
			g_pwm.pwmStep[index] = ((float)tempPwmVal*1.0 / g_pwm.gradualTime[index]);
			
		}else{
			g_pwm.pwmStep[index] = g_pwm.pwmValTarget[index] - g_pwm.pwmValCurr[index];
		}
		
	}else if(g_pwm.pwmValTarget[index] < g_pwm.pwmValCurr[index]){
		g_pwm.addOrDecFlag[index] = PWMA_Decreasing;

		if(g_pwm.gradualTime[index] != 0x00){
			
			tempPwmVal = g_pwm.pwmValCurr[index] - g_pwm.pwmValTarget[index];
			
			g_pwm.pwmStep[index] = ((float)tempPwmVal*1.0 / g_pwm.gradualTime[index]);
			
		}else {
			g_pwm.pwmStep[index] = g_pwm.pwmValCurr[index] - g_pwm.pwmValTarget[index];
		}
	}
	//Dbg_Println(DBG_BIT_SYS_STATUS,"PWM%d Step - %f",index,g_pwm.pwmStep[index]);
	
	g_pwm.irqEnable = TRUE;
}

/*********************************************************************
 * @fn      PWM_SetAutoAdjust
 * @brief   设置PWM自动调光
 * @para  	
 * 		index:	设置通道 		0~3
 * 		mode：	自动调光模式 	0x00:调节到顶端停止	0x01:循环调节	0x02:停止调节
 * 		adj：	调节方向		0x00:递减	0x01:递增	0x02:与上次命令相反
 * 		adj_time：调节时间		亮度0~100的调节时间，单位：ms
 */
void PWM_SetAutoAdjust(U8_T index,U8_T mode,U8_T adj,U16_T adj_time){
	g_pwm.irqEnable = FALSE;
	g_pwmAutoAdj.enable[index] = TRUE;
	
	if(mode == 0x02){
		g_pwmAutoAdj.enable[index] = FALSE;		//停止自动调节
		
		g_pwm.brightnessCurr[index] = (g_pwm.pwmValCurr[index] * 100)  / PWM_OUT_VAL_MAX;		//同步一下当前亮度
		
		if(g_pwm.switchState[index] == 0x00){
			//如果当前回路状态为关，当前输出PWM也应为0
			g_pwm.pwmValCurr[index] = 0;
			g_pwm.pwmFloatValCurr[index] = 0;
		}
	}else{
		g_pwmAutoAdj.adjMode[index] = mode;
	}
	
	if(adj == 0x02){
		if(g_pwmAutoAdj.adjDir[index] == 0x01){
			g_pwmAutoAdj.adjDir[index] = 0x00;
		}else{
			g_pwmAutoAdj.adjDir[index] = 0x01;
		}
	}else if(adj < 0x02){
		g_pwmAutoAdj.adjDir[index] = adj;
	}else{
		g_pwmAutoAdj.adjDir[index] = 0x00;
	}
	
	if(adj_time != 0x00){
		g_pwmAutoAdj.pwmStep[index] = (float)(PWM_OUT_VAL_MAX*1.0 / adj_time);
	}else{
		//循环调光时间最短为100ms
		g_pwmAutoAdj.pwmStep[index] = (float)(PWM_OUT_VAL_MAX*1.0 / 100);			
	}
	
	//Dbg_Println(DBG_BIT_SYS_STATUS,"Adjust PWM%d Step - %f",index,g_pwmAutoAdj.pwmStep[index]);
	g_pwm.irqEnable = TRUE;
}

void PWM_Timer_Enable(void){
	g_pwm.irqEnable = TRUE;
}

void PWM_Timer_Disable(void){
	g_pwm.irqEnable = FALSE;
}

void PWM_Timer_1ms_Task(void){
	U8_T index = 0;
	float temp_float_val = 0;
	
	if(g_pwm.irqEnable == TRUE){
		for(index = 0;index < PWM_OUT_CH_MAX; index++){
			if(g_pwmAutoAdj.enable[index] == FALSE){
				
				//调节至指定亮度
				if(g_pwm.controlFlag[index] == TRUE){
					//当前PWM输出通道，需要进行调节
					if(g_pwm.gradualTime[index] != 0x00){
						if(g_pwm.addOrDecFlag[index] == PWMA_Ascending){
							
							//PWM递增 - 防止溢出
							temp_float_val = g_pwm.pwmFloatValCurr[index] + g_pwm.pwmStep[index];
							if(temp_float_val <= PWM_OUT_VAL_MAX){
								g_pwm.pwmFloatValCurr[index] = temp_float_val;
							}else{
								g_pwm.pwmFloatValCurr[index] = PWM_OUT_VAL_MAX;
							}
							
							g_pwm.pwmValCurr[index] = (U16_T)g_pwm.pwmFloatValCurr[index];
							//调节至目标值，便停止调节
							if(g_pwm.pwmValCurr[index] >= g_pwm.pwmValTarget[index]){
								g_pwm.pwmValCurr[index] = g_pwm.pwmValTarget[index];
								g_pwm.pwmFloatValCurr[index] = g_pwm.pwmValCurr[index];
								g_pwm.controlFlag[index] = FALSE;
							}
							
						}else if(g_pwm.addOrDecFlag[index] == PWMA_Decreasing){
							
							//PWM递减 - 防止溢出
							if(g_pwm.pwmFloatValCurr[index] >= g_pwm.pwmStep[index]){
								g_pwm.pwmFloatValCurr[index] -= g_pwm.pwmStep[index];
							}else{
								g_pwm.pwmFloatValCurr[index] = 0x00;
							}
							
							g_pwm.pwmValCurr[index] = (U16_T)g_pwm.pwmFloatValCurr[index];
							//调节至目标值，便停止调节
							if(g_pwm.pwmValCurr[index] <= g_pwm.pwmValTarget[index]){
								g_pwm.pwmValCurr[index] = g_pwm.pwmValTarget[index];
								g_pwm.pwmFloatValCurr[index] = g_pwm.pwmValCurr[index];
								g_pwm.controlFlag[index] = FALSE;
							}
						}else{
							g_pwm.controlFlag[index] = FALSE;
							//Dbg_Println(DBG_BIT_Debug_STATUS,"controlFlag 3 %d ",index);
						}
					}else {
						//渐变时间为0，直接设置当前通道的PWM值
						g_pwm.pwmValCurr[index] = g_pwm.pwmValTarget[index];
						g_pwm.pwmFloatValCurr[index] = g_pwm.pwmValCurr[index];
						g_pwm.controlFlag[index] = FALSE;
					}
					
					//Dbg_Println(DBG_BIT_SYS_STATUS,"PWM%d %d %f %f",index,g_pwm.pwmValCurr[index],g_pwm.pwmStep[index],g_pwm.pwmFloatValCurr[index]);
					//设置通道的PWM输出的值
					PWM_SetOutDuty(index,g_pwm.pwmValCurr[index]);
				}
			}else {
				
				//自动调光 - 在设置的全局亮度上下限中进行调光
				if(g_pwmAutoAdj.adjDir[index] == 0x00){
					//调节方向 - 递减
					if((g_pwm.pwmFloatValCurr[index] >= g_pwmAutoAdj.pwmStep[index]) && (g_pwm.pwmFloatValCurr[index] >= (float)g_pwm.allPwmDownLimit) ){
						g_pwm.pwmFloatValCurr[index] -= g_pwmAutoAdj.pwmStep[index];
					}else{
						g_pwm.pwmFloatValCurr[index] = (float)g_pwm.allPwmDownLimit;
						
						if(g_pwmAutoAdj.adjMode[index] == 0x01){
							//循环调节
							g_pwmAutoAdj.adjDir[index] = 0x01;
						}else {
							g_pwmAutoAdj.enable[index] = FALSE;		//自动调节完毕
							g_pwm.brightnessCurr[index] = g_pwm.allPwmDownLimit;	//同步一下当前亮度
						}
					}
				}else if(g_pwmAutoAdj.adjDir[index] == 0x01){
					temp_float_val = g_pwm.pwmFloatValCurr[index] + g_pwmAutoAdj.pwmStep[index];
					
					if( (temp_float_val <= PWM_OUT_VAL_MAX) && (g_pwm.pwmFloatValCurr[index] <= (float)g_pwm.allPwmUpLimit) ){
						g_pwm.pwmFloatValCurr[index] = temp_float_val;
					}else{
						g_pwm.pwmFloatValCurr[index] = (float)g_pwm.allPwmUpLimit;
						if(g_pwmAutoAdj.adjMode[index] == 0x01){
							//循环调节
							g_pwmAutoAdj.adjDir[index] = 0x00;
						}else {
							g_pwmAutoAdj.enable[index] = FALSE;		//自动调节完毕
							g_pwm.brightnessCurr[index] = g_pwm.allPwmUpLimit;		//同步一下当前亮度
						}
					}
				}
				
				g_pwm.pwmValCurr[index] = (U16_T)g_pwm.pwmFloatValCurr[index];
				
				//设置通道的PWM输出的值
				if(g_pwm.switchState[index] != 0x00){

					PWM_SetOutDuty(index,g_pwm.pwmValCurr[index]);
				}else{
					/*在回路状态为关的情况下，不进行输出控制*/
					
				}
				
				//Dbg_Println(DBG_BIT_SYS_STATUS,"PWM%d Adjust %d %f %f %d %d",index,g_pwm.pwmValCurr[index],g_pwm.pwmFloatValCurr[index],g_pwmAutoAdj.pwmStep[index],g_pwm.allPwmUpLimit,g_pwm.allPwmDownLimit);
				
			}
			
		}
	}
}


