#include "dip_sw.h"
#include "user_can.h"
#include "user_config.h"

static dipsw_addr_u dipsw_addr = {
	.addr = 0,
};

static bool get_dipsw01_level(void);
static bool get_dipsw02_level(void);
static bool get_dipsw03_level(void);
static bool get_dipsw04_level(void);
static bool get_dipsw05_level(void);
static bool get_dipsw06_level(void);
static bool get_dipsw07_level(void);
static bool get_dipsw08_level(void);

static dipsw_work_s dipsw_work[8] =
{
  {
    .idx = 0,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw01_level,
  },
  {
    .idx = 1,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw02_level,
  },
  {
    .idx = 2,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw03_level,
  },
  {
    .idx = 3,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw04_level,
  },
  {
    .idx = 4,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw05_level,
  },
  {
    .idx = 5,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw06_level,
  },
  {
    .idx = 6,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw07_level,
  },
  {
    .idx = 7,
    .dipsw_stat = 2,
    .dipsw_finish = false,
    .dipsw_on_count = DIP_SW_CHECK_COUNT,
    .dipsw_off_count = DIP_SW_CHECK_COUNT,
    .get_level = get_dipsw08_level,
  },
};

dipsw_upload_func dipsw_upload = NULL;

static void dipsw_pro(void);

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

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

  DIP_SW_GPIO_RCC_ENABLE;

  GPIO_InitStructure.GPIO_Pin = DIP_SW01_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DIP_SW01_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = DIP_SW02_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DIP_SW02_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = DIP_SW03_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DIP_SW03_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = DIP_SW04_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DIP_SW04_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = DIP_SW05_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DIP_SW05_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = DIP_SW06_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DIP_SW06_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = DIP_SW07_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DIP_SW07_GPIO, &GPIO_InitStructure);
}

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

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

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

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

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

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

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

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

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

/*******************************************************************************
  * @函数名称   set_dispsw_addr
  * @函数说明   设置地址
  * @输入参数  	idx：地址位
               stat：状态      
  * @输出参数   无
  * @返回参数   状态
*******************************************************************************/
static void set_dispsw_addr(uint8_t idx, bool stat)
{
  switch(idx)
  {
    case 0:dipsw_addr.dipsw_addr.dipsw01_level = ((stat == true)?1:0); break;
    case 1:dipsw_addr.dipsw_addr.dipsw02_level = ((stat == true)?1:0); break;
    case 2:dipsw_addr.dipsw_addr.dipsw03_level = ((stat == true)?1:0); break;
    case 3:dipsw_addr.dipsw_addr.dipsw04_level = ((stat == true)?1:0); break;
    case 4:dipsw_addr.dipsw_addr.dipsw05_level = ((stat == true)?1:0); break;
    case 5:dipsw_addr.dipsw_addr.dipsw06_level = ((stat == true)?1:0); break;
    case 6:dipsw_addr.dipsw_addr.dipsw07_level = ((stat == true)?1:0); break;
    case 7:dipsw_addr.dipsw_addr.dipsw08_level = ((stat == true)?1:0); break;
  }
}

/*******************************************************************************
  * @函数名称   dipsw_check
  * @函数说明   拨码开关状态检测
  * @输入参数  	dipsw：对象地址     
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void dipsw_check(dipsw_work_s *dipsw)
{
  if(true == dipsw->get_level())
  {
    dipsw->dipsw_off_count = DIP_SW_CHECK_COUNT;
    if(dipsw->dipsw_on_count == 0)
    {
      if(dipsw->dipsw_finish == false)
      {
        dipsw->dipsw_finish = true;
        if(dipsw->dipsw_stat != 1)
        {
          dipsw->dipsw_stat = 1;
          set_dispsw_addr(dipsw->idx, true);
        }
      }
    }
    else{
      dipsw->dipsw_finish = false;
      dipsw->dipsw_on_count--;
    }
  }
  else{
    dipsw->dipsw_on_count = DIP_SW_CHECK_COUNT;
    if(dipsw->dipsw_off_count == 0)
    {
      if(dipsw->dipsw_finish == false)
      {
        dipsw->dipsw_finish = true;
        if(dipsw->dipsw_stat != 0)
        {
          dipsw->dipsw_stat = 0;
          set_dispsw_addr(dipsw->idx, false);
        }
      }
    }
    else{
      dipsw->dipsw_finish = false;
      dipsw->dipsw_off_count--;
    }
  }
}

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

  if(dipsw_upload != NULL)
  {
    dipsw_upload(dipsw_addr.addr);
  }
}

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

    return 0;
}

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

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

