#include "elect_sw.h"
#include "user_elect.h"

static bool get_electsw01_level(void);
static bool get_electsw02_level(void);
static bool get_electsw03_level(void);
static bool get_electsw04_level(void);
static bool get_electsw05_level(void);

static electsw_work_s electsw_work[5] =
{
  {
    .idx = 0,
    .electsw_stat = ELECTSW_STAT_NULL,
    .electsw_finish = false,
    .electsw_on_count = ELECT_SW_CHECK_COUNT,
    .electsw_off_count = ELECT_SW_CHECK_COUNT,
    .get_level = get_electsw01_level,
  },
  {
    .idx = 1,
    .electsw_stat = ELECTSW_STAT_NULL,
    .electsw_finish = false,
    .electsw_on_count = ELECT_SW_CHECK_COUNT,
    .electsw_off_count = ELECT_SW_CHECK_COUNT,
    .get_level = get_electsw02_level,
  },
  {
    .idx = 2,
    .electsw_stat = ELECTSW_STAT_NULL,
    .electsw_finish = false,
    .electsw_on_count = ELECT_SW_CHECK_COUNT,
    .electsw_off_count = ELECT_SW_CHECK_COUNT,
    .get_level = get_electsw03_level,
  },
  {
    .idx = 3,
    .electsw_stat = ELECTSW_STAT_NULL,
    .electsw_finish = false,
    .electsw_on_count = ELECT_SW_CHECK_COUNT,
    .electsw_off_count = ELECT_SW_CHECK_COUNT,
    .get_level = get_electsw04_level,
  },
  {
    .idx = 4,
    .electsw_stat = ELECTSW_STAT_NULL,
    .electsw_finish = false,
    .electsw_on_count = ELECT_SW_CHECK_COUNT,
    .electsw_off_count = ELECT_SW_CHECK_COUNT,
    .get_level = get_electsw05_level,
  },
};

electsw_upload_func electsw_upload = NULL;

static void electsw_pro(void);

/*******************************************************************************
  * @函数名称   electsw_gpio_init
  * @函数说明   GPIO初始化
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void electsw_gpio_init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure={0};

//    PWR_BackupAccessCmd(ENABLE);	//允许修改RTC 和后备寄存器
//    RCC_LSICmd(DISABLE);		//关闭外部低速外部时钟信号功能 后，PC14 PC15 才可以当普通IO用。
//    BKP_TamperPinCmd(DISABLE);		//关闭入侵检测功能，也就是 PC13，也可以当普通IO 使用

  ELECT_SW_GPIO_RCC_ENABLE;

  GPIO_InitStructure.GPIO_Pin = ELECT_SW01_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(ELECT_SW01_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = ELECT_SW02_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(ELECT_SW02_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = ELECT_SW03_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(ELECT_SW03_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = ELECT_SW04_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(ELECT_SW04_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = ELECT_SW05_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(ELECT_SW05_GPIO, &GPIO_InitStructure);
}

/*******************************************************************************
  * @函数名称   vElectsw_init
  * @函数说明   初始化
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void vElectsw_init(void)
{
  electsw_gpio_init();
}

/*******************************************************************************
  * @函数名称   get_electsw01_level
  * @函数说明   读取端口状态
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   状态
*******************************************************************************/
static bool get_electsw01_level(void)
{
  if(0 == ELECT_SW01_IN)
  {
    return true;
  }
  else{
    return false;
  }
}

/*******************************************************************************
  * @函数名称   get_electsw02_level
  * @函数说明   读取端口状态
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   状态
*******************************************************************************/
static bool get_electsw02_level(void)
{
  if(0 == ELECT_SW02_IN)
  {
    return true;
  }
  else{
    return false;
  }
}

/*******************************************************************************
  * @函数名称   get_electsw03_level
  * @函数说明   读取端口状态
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   状态
*******************************************************************************/
static bool get_electsw03_level(void)
{
  if(0 == ELECT_SW03_IN)
  {
    return true;
  }
  else{
    return false;
  }
}

/*******************************************************************************
  * @函数名称   get_electsw04_level
  * @函数说明   读取端口状态
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   状态
*******************************************************************************/
static bool get_electsw04_level(void)
{
  if(0 == ELECT_SW04_IN)
  {
    return true;
  }
  else{
    return false;
  }
}

/*******************************************************************************
  * @函数名称   get_electsw05_level
  * @函数说明   读取端口状态
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   状态
*******************************************************************************/
static bool get_electsw05_level(void)
{
  if(0 == ELECT_SW05_IN)
  {
    return true;
  }
  else{
    return false;
  }
}

/*******************************************************************************
  * @函数名称   electsw_check
  * @函数说明   电磁锁状态检测
  * @输入参数  	electsw     
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void electsw_check(electsw_work_s *electsw)
{
  if(true == electsw->get_level())
  {
    electsw->electsw_off_count = ELECT_SW_CHECK_COUNT;
    if(electsw->electsw_on_count == 0)
    {
      if(electsw->electsw_finish == false)
      {
        electsw->electsw_finish = true;
        if(electsw->electsw_stat != ELECTSW_STAT_OPEN)
        {
          electsw->electsw_stat = ELECTSW_STAT_OPEN;
          if(electsw_upload != NULL)
          {
            PRINT("No.%d elect stat is open\n", electsw->idx);
            electsw_upload(electsw->idx, false);
          }
        }
      }
    }
    else{
      electsw->electsw_finish = false;
      electsw->electsw_on_count--;
    }
  }
  else{
    electsw->electsw_on_count = ELECT_SW_CHECK_COUNT;
    if(electsw->electsw_off_count == 0)
    {
      if(electsw->electsw_finish == false)
      {
        electsw->electsw_finish = true;
        if(electsw->electsw_stat != ELECTSW_STAT_CLOSE)
        {
          electsw->electsw_stat = ELECTSW_STAT_CLOSE;
          if(electsw_upload != NULL)
          {
            PRINT("No.%d elect stat is close\n", electsw->idx);
            electsw_upload(electsw->idx, true);
          }
        }
      }
    }
    else{
      electsw->electsw_finish = false;
      electsw->electsw_off_count--;
    }
  }
}

/*******************************************************************************
  * @函数名称   electsw_pro
  * @函数说明   执行的任务
  * @输入参数  	无    
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void electsw_pro(void)
{
  for(uint8_t i = 0; i < 5; i++)
  {
    electsw_check(&electsw_work[i]);
  }
}

/*******************************************************************************
  * @函数名称   electsw_task_process_event
  * @函数说明   task的event处理回调函数,需要在注册task时候,传进去
  * @输入参数  	task_id：任务ID
               events：事件 
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
uint16_t electsw_task_process_event(uint8_t task_id, uint16_t events)
{
    //event 处理
    if(events & (1 << ELECTSW_QUEUE_TIME))
    {
      electsw_pro();
      return (events ^ (1 << ELECTSW_QUEUE_TIME));
    }

    return 0;
}

/*******************************************************************************
  * @函数名称   electsw_task_start
  * @函数说明   任务开始
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void electsw_task_start(void)
{
    bStatus_t stat = tmos_start_reload_task(elect_task_id, (1 << ELECTSW_QUEUE_TIME), MS1_TO_SYSTEM_TIME(ELECT_SW_INTERVAL));
}

/*******************************************************************************
  * @函数名称   vDipsw_set_upload_func
  * @函数说明   设置上报地址回调函数
  * @输入参数  	func：回调函数指针
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void vElectsw_set_upload_func(electsw_upload_func func)
{
    electsw_upload = func;
}

/*******************************************************************************
  * @函数名称   bElectsw_get_stat
  * @函数说明   获取电磁锁当前状态
  * @输入参数  	idx：电磁锁下标
  * @输出参数   无
  * @返回参数   电磁锁状态
*******************************************************************************/
electsw_stat_e bElectsw_get_stat(uint8_t idx)
{
  return electsw_work[idx].electsw_stat;
}

/*******************************************************************************
  * @函数名称   bElectsw_set_stat
  * @函数说明   设置电磁锁故障状态
  * @输入参数  	idx：电磁锁下标
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void bElectsw_set_fail(uint8_t idx)
{
  electsw_work[idx].electsw_stat = ELECTSW_STAT_FAIL;
}
