#include "hal_led.h"
#include "bsp_gpio.h"
#include "nrf_gpio.h"
#include "usr_config.h"
#include "bsp_time.h"
#include "system.h"
#include "hal_ble_client.h"
#include "bsp_pwm.h"
#include "nrf_delay.h"

#define LED_ENABLE						1
#define LED_DISABLE						0

#define LED_DEFAULT_NUMBER		4

#define ONE_LED_LIGHT_TIME		(3*4*8*4*0.125)		//us

//高位先发，按照GRB的顺序发送数据
//50us以上reset
//#define WS_L								0,0x8000,0x8000,0x8000
//#define WS_H								0,0,0,0x8000

static uint32_t led_channel[4] 																= {PIN_LED_CONTROL,NRF_DRV_PWM_PIN_NOT_USED,NRF_DRV_PWM_PIN_NOT_USED,NRF_DRV_PWM_PIN_NOT_USED};
static uint16_t led_pwm_cycle_time  													= 3;		//1 -> 0.125us
static uint32_t led_pwm_mode																	=	PWM_FLAG_STOP;
static pwm_values_common_t led_color_seq_values[3][4*8]				= {0};
static nrf_pwm_sequence_t *led_color_seq 											= NULL;
static const uint16_t WS_H[4] 																= {0,0,0,0x8000};
static const uint16_t WS_L[4] 																= {0,0x8000,0x8000,0x8000};


struct WS_t{
	uint8_t  onoff; 
	uint32_t color;		//颜色
};
static struct WS_t m_wsled[MEMBER_NUM_OF_LED]									=	{0};


/**
	@brief 设置灯的时序
	@param color - [in] 灯的颜色
	@return 无
*/
static void WS2812_DisplayDot(uint32_t col)
{
	uint32_t col_r = (col & 0x00FF0000) >> 16;
	uint32_t col_g = (col & 0x0000FF00) >> 8;
	uint32_t col_b = col & 0x000000FF;
	
	uint32_t t = 0x80;
	uint32_t index = 0;
	for(int i=0;i<8;i++)
	{
		index = i*4;
		if(col_g & t){
			led_color_seq_values[0][index+0] = WS_H[0];
			led_color_seq_values[0][index+1] = WS_H[1];
			led_color_seq_values[0][index+2] = WS_H[2];
			led_color_seq_values[0][index+3] = WS_H[3];
		}else{
			led_color_seq_values[0][index+0] = WS_L[0];
			led_color_seq_values[0][index+1] = WS_L[1];
			led_color_seq_values[0][index+2] = WS_L[2];
			led_color_seq_values[0][index+3] = WS_L[3];
		}
		index = i*4;
		if(col_r & t){
			led_color_seq_values[1][index+0] = WS_H[0];
			led_color_seq_values[1][index+1] = WS_H[1];
			led_color_seq_values[1][index+2] = WS_H[2];
			led_color_seq_values[1][index+3] = WS_H[3];
		}else{
			led_color_seq_values[1][index+0] = WS_L[0];
			led_color_seq_values[1][index+1] = WS_L[1];
			led_color_seq_values[1][index+2] = WS_L[2];
			led_color_seq_values[1][index+3] = WS_L[3];
		}
		index = i*4;
		if(col_b & t){
			led_color_seq_values[2][index+0] = WS_H[0];
			led_color_seq_values[2][index+1] = WS_H[1];
			led_color_seq_values[2][index+2] = WS_H[2];
			led_color_seq_values[2][index+3] = WS_H[3];
		}else{
			led_color_seq_values[2][index+0] = WS_L[0];
			led_color_seq_values[2][index+1] = WS_L[1];
			led_color_seq_values[2][index+2] = WS_L[2];
			led_color_seq_values[2][index+3] = WS_L[3];
		}
		t = t>>1;
	}		

}

static uint8_t Led_ChangFlag_PRO =0 ;
static uint8_t Led_PRO_Current =LED_NONE ;
//强制关闭LED
void LED_Close_Enforce(void){
	 nrf_gpio_pin_write(PIN_LED_ENABLE,LED_DISABLE); 
	 Led_PRO_Current = LED_NONE;
	 Led_ChangFlag_PRO =0 ;
}

void LED_Stop(uint8_t n)
{
	if(n>=MEMBER_NUM_OF_LED) return;
	m_wsled[n].onoff = 0;
	m_wsled[n].color = COLOR_BLACK;
	if(n >= Led_PRO_Current) {
		Led_ChangFlag_PRO =1;
	}
}

void LED_Start(uint8_t n,uint32_t color)
{ 
	if(n>=MEMBER_NUM_OF_LED) return;
	m_wsled[n].onoff = 1;
	m_wsled[n].color = color;
	if(n >= Led_PRO_Current) {
//		SEGGER_RTT_printf(0,"LED_Start:%d,%X\n",n,color);
		Led_PRO_Current =n;
		Led_ChangFlag_PRO =1;
	}
}

void LED_Process(void)
{
  static uint8_t state =0;
	uint8_t i =0;
	switch(state){
		case 0:
					if(Led_ChangFlag_PRO){
						state =1;
						nrf_gpio_pin_write(PIN_LED_ENABLE,LED_ENABLE);
					}
					break;
		case 1:
			  if(Led_PRO_Current < MEMBER_NUM_OF_LED ){
						if(1 == m_wsled[Led_PRO_Current].onoff){	//关闭所有灯
								WS2812_DisplayDot(m_wsled[Led_PRO_Current].color);
							  SetSimplePwmPlayBack(led_color_seq, LED_DEFAULT_NUMBER, led_pwm_mode);
						}
						else{
							for(i =Led_PRO_Current;i > 0;i--){//寻找下一个需要控制LED的事件
								  if(1 == m_wsled[i].onoff){
										 Led_PRO_Current = i;
										 WS2812_DisplayDot(m_wsled[i].color);
							       SetSimplePwmPlayBack(led_color_seq, LED_DEFAULT_NUMBER, led_pwm_mode);
										 break;
									}
							}
							if(0 == i){//找不到需要控制的LED事件
								nrf_gpio_pin_write(PIN_LED_ENABLE,LED_DISABLE);
								Led_PRO_Current = LED_NONE;
							}
						}
				}
				Led_ChangFlag_PRO = 0;
			  state =0;
		    break;
	}
}



#if DEBUG_LEDRGB

void LED_Run(void) 
{
	#if DEBUG_LEDRGB
	static uint32_t temp=0;
		if(temp==0){
			LED_Start(LED_RUN,COLOR_BLACK);
		}else if(temp==1){
			LED_Start(LED_RUN,COLOR_WHITE);
		}else if(temp==2){
			LED_Start(LED_RUN,COLOR_RED);
		}else if(temp==3){
			LED_Start(LED_RUN,COLOR_BLUE);
		}else if(temp==4){
			LED_Start(LED_RUN,COLOR_ORANGE);
		}else if(temp==5){
			LED_Start(LED_RUN,COLOR_PURPLE);
		}else if(temp==6){
			LED_Start(LED_RUN,COLOR_YELLOW);
		}else if(temp==7){
			LED_Start(LED_RUN,COLOR_CYAN);
		}
		if(++temp>=8) temp = 0;
//		SEGGER_RTT_printf(0,"LED_Run,%d\n",temp);;
	#else
	nrf_gpio_pin_toggle(PIN_LED_RUN);
	#endif
}

void LED_RGB_Init(void)
{
	Process_Start(500,"LED_Run",LED_Run);
	Process_SetHoldOn(LED_Run,1);
}
#endif

void cb_LED_Wakeup(uint32_t t)
{
	Pwm_Initialize();
}

void cb_LED_Sleep(uint32_t t)
{
	nrf_gpio_pin_write(PIN_LED_ENABLE,LED_DISABLE);
	Pwm_UnInitialize();
}

void LED_Init(void)
{	
	SetPwm_BaseClock(NRF_PWM_CLK_8MHz);
	SetPwm_Channels(led_channel[0], led_channel[1], led_channel[2], led_channel[3]);
	SetPwm_DutyCycleThreshold(led_pwm_cycle_time);
	Pwm_Initialize();
	
	led_color_seq = Pwm_SetComSequence(led_color_seq_values[0], PWM_SEQUENCE_VALUES_LEN(led_color_seq_values),0,0);
	
	nrf_gpio_cfg_output(PIN_LED_ENABLE); 	nrf_gpio_pin_write(PIN_LED_ENABLE,LED_ENABLE);
	nrf_gpio_cfg_output(PIN_LED_RUN); 	nrf_gpio_pin_write(PIN_LED_RUN,LED_SMALL_DISABLE);
	Process_Start(10,"LED_Process",LED_Process);
	#if DEBUG_LEDRGB
	LED_RGB_Init();
	#endif
	
	Sleep_Regist(cb_LED_Sleep);
	Wakeup_Regist(cb_LED_Wakeup);
}



