#include "user_led.h"
#include "define.h"
#include "stdarg.h"

tmosTaskID led_task_id = INVALID_TASK_ID;

static uint32_t alarm_stat = 0;

static uint16_t led_task_process_event(uint8_t task_id, uint16_t events);
static void led_dev_duty(uint16_t duty);
static void led_01_duty(uint16_t duty);
static void led_02_duty(uint16_t duty);
static void led_03_duty(uint16_t duty);
static void led_04_duty(uint16_t duty);
static void led_05_duty(uint16_t duty);

static led_work_s led_work[LED_TYPE_MAX] = {
  {
      .idx = DEV_LED,
      .set_duty = led_dev_duty,
      .color = RED_LED,
      .workStat = LED_WORK_OFF,
      .viewStat = LED_VIEW_NULL,
      .single_flicker_period = 0,
      .flicker_period = 0,
      .flicker_onperiod = 0,
      .flicker_count = 0,
      .duty_on = 95,
      .duty_value = 0,
      .single_on_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .on_durationTime = 0,				    //PWM变化结束后持续时间，单位：ms
      .single_off_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .off_durationTime = 0,				//PWM变化结束后持续时间，单位：ms
  },
  {
      .idx = LED_01,
      .set_duty = led_01_duty,
      .color = RED_LED,
      .workStat = LED_WORK_OFF,
      .viewStat = LED_VIEW_NULL,
      .single_flicker_period = 0,
      .flicker_period = 0,
      .flicker_onperiod = 0,
      .flicker_count = 0,
      .duty_on = 95,
      .duty_value = 0,
      .single_on_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .on_durationTime = 0,				    //PWM变化结束后持续时间，单位：ms
      .single_off_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .off_durationTime = 0,				//PWM变化结束后持续时间，单位：ms
  },
  {
      .idx = LED_02,
      .set_duty = led_02_duty,
      .color = RED_LED,
      .workStat = LED_WORK_OFF,
      .viewStat = LED_VIEW_NULL,
      .single_flicker_period = 0,
      .flicker_period = 0,
      .flicker_onperiod = 0,
      .flicker_count = 0,
      .duty_on = 95,
      .duty_value = 0,
      .single_on_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .on_durationTime = 0,				    //PWM变化结束后持续时间，单位：ms
      .single_off_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .off_durationTime = 0,				//PWM变化结束后持续时间，单位：ms
  },
  {
      .idx = LED_03,
      .set_duty = led_03_duty,
      .color = RED_LED,
      .workStat = LED_WORK_OFF,
      .viewStat = LED_VIEW_NULL,
      .single_flicker_period = 0,
      .flicker_period = 0,
      .flicker_onperiod = 0,
      .flicker_count = 0,
      .duty_on = 95,
      .duty_value = 0,
      .single_on_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .on_durationTime = 0,				    //PWM变化结束后持续时间，单位：ms
      .single_off_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .off_durationTime = 0,				//PWM变化结束后持续时间，单位：ms
  },
  {
      .idx = LED_04,
      .set_duty = led_04_duty,
      .color = RED_LED,
      .workStat = LED_WORK_OFF,
      .viewStat = LED_VIEW_NULL,
      .single_flicker_period = 0,
      .flicker_period = 0,
      .flicker_onperiod = 0,
      .flicker_count = 0,
      .duty_on = 95,
      .duty_value = 0,
      .single_on_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .on_durationTime = 0,				    //PWM变化结束后持续时间，单位：ms
      .single_off_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .off_durationTime = 0,				//PWM变化结束后持续时间，单位：ms
  },
  {
      .idx = LED_05,
      .set_duty = led_05_duty,
      .color = RED_LED,
      .workStat = LED_WORK_OFF,
      .viewStat = LED_VIEW_NULL,
      .single_flicker_period = 0,
      .flicker_period = 0,
      .flicker_onperiod = 0,
      .flicker_count = 0,
      .duty_on = 95,
      .duty_value = 0,
      .single_on_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .on_durationTime = 0,				    //PWM变化结束后持续时间，单位：ms
      .single_off_durationTime = 0,			//PWM变化结束后持续时间，单位：ms
      .off_durationTime = 0,				//PWM变化结束后持续时间，单位：ms
  },
};

/*******************************************************************************
  * @函数名称   led_pwm_init
  * @函数说明   初始化
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_pwm_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure={0};
    TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
    TIM_OCInitTypeDef TIM_OutputCompareInitStructure;
    TIM_BDTRInitTypeDef BDTR_Structure;
    TIM5_TimeBaseInitTypeDef TIM5_BaseInitStructure;
    TIM5_OCInitTypeDef TIM5_OutputCompareInitStructure;
    TIM5_BDTRInitTypeDef BDTR5_Structure;

    LED_GPIO_RCC_ENABLE;
    GPIO_InitStructure.GPIO_Pin = DEV_LED_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DEV_LED_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_01_R_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_01_R_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_01_G_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_01_G_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_02_R_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_02_R_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_02_G_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_02_G_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_03_R_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_03_R_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_03_G_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_03_G_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_04_R_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_04_R_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_04_G_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_04_G_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_05_R_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_05_R_GPIO, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = LED_05_G_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_05_G_GPIO, &GPIO_InitStructure );

    LED_PWM_RCC_ENABLE;
#ifdef LED_REMAPCONFIG_ENABLE
    LED_REMAPCONFIG_ENABLE;
#endif
    
    TIM_BaseInitStructure.TIM_Period = TIM_LED_PERIOD;
    TIM_BaseInitStructure.TIM_Prescaler = TIM_LED_PRESCALER - 1;
    TIM_BaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
    TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM3_LED_TYPE, &TIM_BaseInitStructure);
    TIM_TimeBaseInit(TIM4_LED_TYPE, &TIM_BaseInitStructure);

    TIM_OutputCompareInitStructure.TIM_OCMode =TIM_OCMode_PWM1;				//占空比设置的高电平
    TIM_OutputCompareInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OutputCompareInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_Low;
    TIM_OutputCompareInitStructure.TIM_OutputState =TIM_OutputState_Enable;
    TIM_OutputCompareInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    TIM_OutputCompareInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OutputCompareInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
    TIM_OutputCompareInitStructure.TIM_Pulse = 0;

    BDTR_Structure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
    BDTR_Structure.TIM_Break = TIM_Break_Disable;
    BDTR_Structure.TIM_BreakPolarity = TIM_BreakPolarity_High;
    BDTR_Structure.TIM_DeadTime = 0x80;
    BDTR_Structure.TIM_LOCKLevel = TIM_LOCKLevel_1;
    BDTR_Structure.TIM_OSSIState = TIM_OSSIState_Enable;
    BDTR_Structure.TIM_OSSRState = TIM_OSSRState_Enable;
    TIM_BDTRConfig(TIM3_LED_TYPE,&BDTR_Structure);
    TIM_BDTRConfig(TIM4_LED_TYPE,&BDTR_Structure);

    LED_01_R_INIT(&TIM_OutputCompareInitStructure);
    LED_01_G_INIT(&TIM_OutputCompareInitStructure);
    LED_02_R_INIT(&TIM_OutputCompareInitStructure);
    LED_02_G_INIT(&TIM_OutputCompareInitStructure);
    LED_03_R_INIT(&TIM_OutputCompareInitStructure);
    LED_03_G_INIT(&TIM_OutputCompareInitStructure);

    TIM5_BaseInitStructure.TIM_Period = TIM_LED_PERIOD;
    TIM5_BaseInitStructure.TIM_Prescaler = TIM_LED_PRESCALER - 1;
    TIM5_BaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
    TIM5_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM5_BaseInitStructure.TIM_RepetitionCounter = 0;
    TIM5_TimeBaseInit(&TIM5_BaseInitStructure);

    TIM5_OutputCompareInitStructure.TIM_OCMode =TIM_OCMode_PWM1;				//占空比设置的高电平
    TIM5_OutputCompareInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM5_OutputCompareInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_Low;
    TIM5_OutputCompareInitStructure.TIM_OutputState =TIM_OutputState_Enable;
    TIM5_OutputCompareInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    TIM5_OutputCompareInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM5_OutputCompareInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
    TIM5_OutputCompareInitStructure.TIM_Pulse = 0;

    BDTR5_Structure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
    BDTR5_Structure.TIM_Break = TIM_Break_Disable;
    BDTR5_Structure.TIM_BreakPolarity = TIM_BreakPolarity_High;
    BDTR5_Structure.TIM_DeadTime = 0x80;
    BDTR5_Structure.TIM_LOCKLevel = TIM_LOCKLevel_1;
    BDTR5_Structure.TIM_OSSIState = TIM_OSSIState_Enable;
    BDTR5_Structure.TIM_OSSRState = TIM_OSSRState_Enable;
    TIM5_BDTRConfig(&BDTR5_Structure);

    LED_04_R_INIT(&TIM5_OutputCompareInitStructure);
    LED_04_G_INIT(&TIM5_OutputCompareInitStructure);
    LED_05_R_INIT(&TIM5_OutputCompareInitStructure);
    LED_05_G_INIT(&TIM5_OutputCompareInitStructure);

    LED_01_R_RUN;
    LED_01_G_RUN;
    LED_02_R_RUN;
    LED_02_G_RUN;
    LED_03_R_RUN;
    LED_03_G_RUN;
    LED_04_R_RUN;
    LED_04_G_RUN;
    LED_05_R_RUN;
    LED_05_G_RUN;

    DEV_LED_OFF;

    LED_01_R_COMPARE(0);
    LED_01_G_COMPARE(0);
    LED_02_R_COMPARE(0);
    LED_02_G_COMPARE(0);
    LED_03_R_COMPARE(0);
    LED_03_G_COMPARE(0);
    LED_04_R_COMPARE(0);
    LED_04_G_COMPARE(0);
    LED_05_R_COMPARE(0);
    LED_05_G_COMPARE(0);

    TIM_Cmd(TIM3_LED_TYPE,ENABLE);
    TIM_Cmd(TIM4_LED_TYPE,ENABLE);
    TIM_Cmd(TIM5_LED_TYPE,ENABLE);
}

/*******************************************************************************
  * @函数名称   led_dev_duty
  * @函数说明   设置设备指示灯PWM百分比
  * @输入参数  	duty：百分比
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_dev_duty(uint16_t duty)
{
    if(duty == 0)
    {
        DEV_LED_OFF;
    }
    else{
        DEV_LED_ON;
    }
}

/*******************************************************************************
  * @函数名称   led_01_duty
  * @函数说明   设置1号仓指示灯PWM百分比
  * @输入参数  	duty：百分比
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_01_duty(uint16_t duty)
{
    uint16_t value = TIM_LED_PERIOD * duty / 100;
    if(led_work[LED_01].color == RED_LED)
    {
        LED_01_G_COMPARE(LED_OFF_DUTY);
        LED_01_R_COMPARE(duty);
    }
    else if(led_work[LED_01].color == GREEN_LED)
    {
        LED_01_R_COMPARE(LED_OFF_DUTY);
        LED_01_G_COMPARE(duty);
    }
    else if(led_work[LED_01].color == YELLOW_LED)
    {
        LED_01_R_COMPARE(duty);
        LED_01_G_COMPARE(duty);
    }
}

/*******************************************************************************
  * @函数名称   led_02_duty
  * @函数说明   设置2号仓指示灯PWM百分比
  * @输入参数  	duty：百分比
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_02_duty(uint16_t duty)
{
    uint16_t value = TIM_LED_PERIOD * duty / 100;
    if(led_work[LED_02].color == RED_LED)
    {
        LED_02_G_COMPARE(LED_OFF_DUTY);
        LED_02_R_COMPARE(duty);
    }
    else if(led_work[LED_02].color == GREEN_LED)
    {
        LED_02_R_COMPARE(LED_OFF_DUTY);
        LED_02_G_COMPARE(duty);
    }
    else if(led_work[LED_02].color == YELLOW_LED)
    {
        LED_02_R_COMPARE(duty);
        LED_02_G_COMPARE(duty);
    }
}

/*******************************************************************************
  * @函数名称   led_03_duty
  * @函数说明   设置3号仓指示灯PWM百分比
  * @输入参数  	duty：百分比
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_03_duty(uint16_t duty)
{
    uint16_t value = TIM_LED_PERIOD * duty / 100;
    if(led_work[LED_03].color == RED_LED)
    {
        LED_03_G_COMPARE(LED_OFF_DUTY);
        LED_03_R_COMPARE(duty);
    }
    else if(led_work[LED_03].color == GREEN_LED)
    {
        LED_03_R_COMPARE(LED_OFF_DUTY);
        LED_03_G_COMPARE(duty);
    }
    else if(led_work[LED_03].color == YELLOW_LED)
    {
        LED_03_R_COMPARE(duty);
        LED_03_G_COMPARE(duty);
    }
}

/*******************************************************************************
  * @函数名称   led_04_duty
  * @函数说明   设置4号仓指示灯PWM百分比
  * @输入参数  	duty：百分比
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_04_duty(uint16_t duty)
{
    uint16_t value = TIM_LED_PERIOD * duty / 100;
    if(led_work[LED_04].color == RED_LED)
    {
        LED_04_G_COMPARE(LED_OFF_DUTY);
        LED_04_R_COMPARE(duty);
    }
    else if(led_work[LED_04].color == GREEN_LED)
    {
        LED_04_R_COMPARE(LED_OFF_DUTY);
        LED_04_G_COMPARE(duty);
    }
    else if(led_work[LED_04].color == YELLOW_LED)
    {
        LED_04_R_COMPARE(duty);
        LED_04_G_COMPARE(duty);
    }
}

/*******************************************************************************
  * @函数名称   led_05_duty
  * @函数说明   设置5号仓指示灯PWM百分比
  * @输入参数  	duty：百分比
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_05_duty(uint16_t duty)
{
    uint16_t value = TIM_LED_PERIOD * duty / 100;
    if(led_work[LED_05].color == RED_LED)
    {
        LED_05_G_COMPARE(LED_OFF_DUTY);
        LED_05_R_COMPARE(duty);
    }
    else if(led_work[LED_05].color == GREEN_LED)
    {
        LED_05_R_COMPARE(LED_OFF_DUTY);
        LED_05_G_COMPARE(duty);
    }
    else if(led_work[LED_05].color == YELLOW_LED)
    {
        LED_05_R_COMPARE(duty);
        LED_05_G_COMPARE(duty);
    }
}

/*******************************************************************************
  * @函数名称   led_invert
  * @函数说明   LED闪烁处理
  * @输入参数  	led_work：led灯结构体直针
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_invert(led_work_s *led_work)
{
    if(led_work->flicker_count > 0)
    {
        if(led_work->single_flicker_period == 0)
        {
            led_work->single_flicker_period = led_work->flicker_period;
            led_work->stat = LED_STAT_ON;
            led_work->set_duty(LED_ON_DUTY);
        }
        else if(led_work->single_flicker_period == (led_work->flicker_period - led_work->flicker_onperiod))
        {
            led_work->single_flicker_period--;
            led_work->stat = LED_STAT_OFF;
            led_work->set_duty(LED_OFF_DUTY);
            led_work->flicker_count--;
        }
        else{
            led_work->single_flicker_period--;
        }
    }
    else{
        led_work->workStat = LED_WORK_OFF;
        led_work->set_duty(LED_OFF_DUTY);
    }
}

/*******************************************************************************
  * @函数名称   led_heart
  * @函数说明   LED呼吸灯处理
  * @输入参数  	led_work：led灯结构体直针
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_heart(led_work_s *led_work)
{
  if(led_work->flicker_count > 0)
  {
      uint32_t off_period = led_work->flicker_period - led_work->flicker_onperiod;
      if(led_work->single_flicker_period == 0)
      {
        led_work->single_flicker_period = led_work->flicker_period;
        led_work->duty_value = 0;
        led_work->single_off_durationTime = led_work->off_durationTime;
        led_work->set_duty(led_work->duty_value);
        led_work->flicker_count--;
      }
      else if(led_work->single_flicker_period == off_period)
      {
        led_work->single_flicker_period--;
        led_work->duty_value = led_work->duty_on;
        led_work->single_on_durationTime = led_work->on_durationTime;
        led_work->set_duty(led_work->duty_value);
      }
      else{
        if(led_work->single_flicker_period > off_period)
        {
            if(led_work->single_off_durationTime == 0)
            {
                led_work->single_flicker_period--;
                led_work->duty_value = (led_work->flicker_period - led_work->single_flicker_period) * 100 / led_work->flicker_onperiod;
                led_work->set_duty(led_work->duty_value);
            }
            else{
                led_work->single_off_durationTime--;
            }
        }
        else{
            if(led_work->single_on_durationTime == 0)
            {
                led_work->single_flicker_period--;
                led_work->duty_value = led_work->single_flicker_period * 100 / off_period;
                led_work->set_duty(led_work->duty_value);
            }
            else{
                led_work->single_on_durationTime--;
            }
        }
      }
  }
  else{
      led_work->workStat = LED_WORK_OFF;
  }
}

/*******************************************************************************
  * @函数名称   led_indication
  * @函数说明   LED灯处理
  * @输入参数  	led_work：led灯结构体直针
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_indication(led_work_s *led_work)
{
    switch(led_work->workStat)
    {
        case LED_WORK_OFF:
        {
            break;
        }
        case LED_WORK_ON:
        {
            break;
        }
        case LED_WORK_INVERT:
        {
            led_invert(led_work);
            break;
        }
        case LED_WORK_BREATHE:
        {
            led_heart(led_work);
            break;
        }
        default:break;
    }
}

/*******************************************************************************
  * @函数名称   led_task
  * @函数说明   LED任务
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void led_task(void)
{
    for(int i = 0; i < LED_TYPE_MAX; i++)
    {
	    led_indication(&led_work[i]);
    }
}

/*******************************************************************************
  * @函数名称   led_task
  * @函数说明   task的event处理回调函数,需要在注册task时候,传进去
  * @输入参数  	task_id：任务ID
               events：事件
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static uint16_t led_task_process_event(uint8_t task_id, uint16_t events)
{
    //event 处理
    if(events & (1 << LED_QUEUE_TIME))
    {
        led_task();
        return (events ^ (1 << LED_QUEUE_TIME)); //异或的方式清除该事件运行标志，并返回未运行的事件标志
    }

    return 0;
}

/*******************************************************************************
  * @函数名称   set_led_indication
  * @函数说明   LED参数设置
  * @输入参数  	type：LED灯号
               color：颜色
               workStat：状态
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
bool set_led_indication(LED_TYPE type, LED_COLOR color, LED_WORK_STAT work_stat, ...)
{
    bool stat = false;

    if(type >= LED_TYPE_MAX)
    {
	    goto exit;
    }

    if(color > YELLOW_LED)
    {
	    goto exit;
    }

    if(work_stat == LED_WORK_OFF || work_stat == LED_WORK_ON)
    {
        led_work[type].color = color;
        led_work[type].workStat = work_stat;
        led_work[type].set_duty((work_stat == LED_WORK_ON) ? LED_ON_DUTY : LED_OFF_DUTY);

        stat = true;
    }
    else if(work_stat == LED_WORK_INVERT || work_stat == LED_WORK_BREATHE)
    {
        led_work[type].color = color;
        led_work[type].workStat = work_stat;
        led_work[type].duty_value = 0;
        led_work[type].stat = LED_STAT_OFF;

        va_list ap;    						//保存所有参数
        va_start(ap, work_stat);	//第一个参数的位置
        led_work[type].flicker_period = va_arg(ap, uint32_t)/LED_INTERVAL;
        led_work[type].flicker_onperiod = va_arg(ap, uint32_t)/LED_INTERVAL;
        led_work[type].flicker_count = va_arg(ap, uint32_t);
        if(led_work[type].flicker_count == 0)
        {
            led_work[type].flicker_count = 0x7FFFFFFF;
        }
        led_work[type].single_flicker_period = led_work[type].flicker_period;

        if(work_stat == LED_WORK_BREATHE)
        {
            led_work[type].on_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
            led_work[type].off_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
            led_work[type].single_on_durationTime = led_work[type].on_durationTime;
            led_work[type].single_off_durationTime = led_work[type].off_durationTime;
        }

        va_end(ap);

        stat = true;
    }
exit:
    return stat;
}

/*******************************************************************************
  * @函数名称   led_task_init
  * @函数说明   LED任务初始化
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void led_task_init(void)
{
    led_task_id  = TMOS_ProcessEventRegister(led_task_process_event);
    PRINT("led_task_id=%d\n", led_task_id);
    led_pwm_init();
}

/*******************************************************************************
  * @函数名称   led_task_start
  * @函数说明   LED任务开始
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void led_task_start(void)
{
    bStatus_t stat = tmos_start_reload_task(led_task_id, (1 << LED_QUEUE_TIME), MS1_TO_SYSTEM_TIME(LED_INTERVAL));
}

/*******************************************************************************
  * @函数名称   vUser_led_set_view_stat
  * @函数说明   设置LED显示状态
  * @输入参数  	stat：led显示状态
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void vUser_led_set_view_stat(LED_TYPE idx, led_view_stat_e stat)
{
    PRINT("set No.%d led stat:%d\n", idx + 1, stat);
    led_work[idx + 1].viewStat = stat;
    if(alarm_stat == 0)
    {
        switch(stat)
        {
            case LED_VIEW_ALARM:set_led_indication(idx + 1, YELLOW_LED, LED_WORK_INVERT, 1000, 500, 0);break;                       //报警
            case LED_VIEW_WARN:set_led_indication(idx + 1, YELLOW_LED, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);break;            //警告
            case LED_VIEW_LOCK_ELECT:set_led_indication(idx + 1, RED_LED, LED_WORK_ON);break;                                       //有挂锁并上锁
            case LED_VIEW_NOLOCK_ELECT:set_led_indication(idx + 1, RED_LED, LED_WORK_BREATHE, 500, 250, 0, 100, 100);break;         //无挂锁并上锁
            case LED_VIEW_LOCK_NOELECT:set_led_indication(idx + 1, GREEN_LED, LED_WORK_BREATHE, 500, 250, 0, 100, 100);break;       //有挂锁没上锁
            case LED_VIEW_NOLOCK_NOELECT:set_led_indication(idx + 1, GREEN_LED, LED_WORK_ON);break;                                 //无挂锁没上锁
            default:break;
        }
    }
}

/*******************************************************************************
  * @函数名称   vUser_led_set_alarm_view
  * @函数说明   设置LED故障显示状态
  * @输入参数  	alarmStat：故障类型
                stat：故障状态
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void vUser_led_set_alarm_view(led_all_alarm_stat_e alarmStat, bool stat)
{
    if(stat == true)
    {
        alarm_stat |= (1 << alarmStat);
    }
    else{
        alarm_stat &= ~(1 << alarmStat);
    }

    if((alarm_stat & (1 << LED_ALL_ALARM_RST)) != 0)
    {
        for(int i = 1; i < LED_TYPE_MAX; i++)
        {
            set_led_indication(i, YELLOW_LED, LED_WORK_INVERT, 1000, 500, 0, 0, 0);
        }
    }
    else if((alarm_stat & (1 << LED_ALL_ALARM_BLE)) != 0)
    {
        for(int i = 1; i < LED_TYPE_MAX; i++)
        {
            set_led_indication(i, GREEN_LED, LED_WORK_INVERT, 200, 100, 0, 0, 0);
        }
    }
    else if((alarm_stat & (1 << LED_ALL_ALARM_CAN_IDX_ERROR)) != 0)
    {
        for(int i = 1; i < LED_TYPE_MAX; i++)
        {
            set_led_indication(i, YELLOW_LED, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);
        }
    }
    else if((alarm_stat & (1 <<  LED_ALL_ALARM_OFFLINE)) != 0)
    {
        for(int i = 1; i < LED_TYPE_MAX; i++)
        {
            set_led_indication(i, YELLOW_LED, LED_WORK_BREATHE, 300, 150, 0, 100, 100);
        }
    }
    else if(alarm_stat == 0)
    {
        for(int i = 1; i < LED_TYPE_MAX; i++)
        {
            vUser_led_set_view_stat(i - 1, led_work[i].viewStat);
        }
    }
}
