#include "includes.h"

volatile uint8_t Key_Wakeup = 0;		   // 是否按键唤醒

// 485串口接收的循环缓冲
#define KEY_TASKM_DATA_COUNT 3
loopbuff_t Key_TaskM;
uint8_t Key_TaskM_Data[sizeof(uint8_t) * (KEY_TASKM_DATA_COUNT + 1)] = {0};
// 485串口接收的信号量
SemaphoreHandle_t Key_Semaphore = NULL;    // 二值信号量句柄



void Key_Init(void) 
{
  LL_EXTI_InitTypeDef EXTI_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);

  /**/
 // LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTE, LL_SYSCFG_EXTI_LINE2);

  /**/
  LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTB, LL_SYSCFG_EXTI_LINE3);

  /**/
  LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTB, LL_SYSCFG_EXTI_LINE4);

  /**/
  LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTB, LL_SYSCFG_EXTI_LINE5);

  /**/
 // LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTE, LL_SYSCFG_EXTI_LINE6);

  /**/
//  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_2;
//  EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
//  EXTI_InitStruct.LineCommand = ENABLE;
//  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
//  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
//  LL_EXTI_Init(&EXTI_InitStruct);

  /**/
  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_3;
  EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
  EXTI_InitStruct.LineCommand = ENABLE;
  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
  LL_EXTI_Init(&EXTI_InitStruct);

  /**/
  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_4;
  EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
  EXTI_InitStruct.LineCommand = ENABLE;
  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
  LL_EXTI_Init(&EXTI_InitStruct);

  /**/
  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_5;
  EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
  EXTI_InitStruct.LineCommand = ENABLE;
  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
  LL_EXTI_Init(&EXTI_InitStruct);

//  /**/
//  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_6;
//  EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
//  EXTI_InitStruct.LineCommand = ENABLE;
//  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
//  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
//  LL_EXTI_Init(&EXTI_InitStruct);

  /**/
//  LL_GPIO_SetPinPull(GPIOE, LL_GPIO_PIN_2, LL_GPIO_PULL_NO);

  /**/
  LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_3, LL_GPIO_PULL_NO);

  /**/
  LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_4, LL_GPIO_PULL_NO);

  /**/
  LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_5, LL_GPIO_PULL_NO);

  /**/
 // LL_GPIO_SetPinPull(GPIOE, LL_GPIO_PIN_6, LL_GPIO_PULL_NO);

  /**/
 // LL_GPIO_SetPinMode(GPIOE, LL_GPIO_PIN_2, LL_GPIO_MODE_INPUT);

  /**/
  LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_3, LL_GPIO_MODE_INPUT);

  /**/
  LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_4, LL_GPIO_MODE_INPUT);

  /**/
  LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_5, LL_GPIO_MODE_INPUT);

  /**/
 // LL_GPIO_SetPinMode(GPIOE, LL_GPIO_PIN_6, LL_GPIO_MODE_INPUT);
}

void Key_Open()
{
	// 分配循环缓冲
	LoopBuff_Create(&Key_TaskM, sizeof(uint8_t), KEY_TASKM_DATA_COUNT, 0, (uint32_t) Key_TaskM_Data);
	// 创建信号量
	Key_Semaphore = xSemaphoreCreateBinary();
	
  /* EXTI interrupt init*/
//  NVIC_SetPriority(EXTI2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
//  NVIC_EnableIRQ(EXTI2_IRQn);
  NVIC_SetPriority(EXTI3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
  NVIC_EnableIRQ(EXTI3_IRQn);
  NVIC_SetPriority(EXTI4_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
  NVIC_EnableIRQ(EXTI4_IRQn);
  NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
  NVIC_EnableIRQ(EXTI9_5_IRQn);
}

// 处理按键
void Key_Handler(void) 
{
	static uint32_t key_tick = 0;
	uint32_t tick = GetTickCount();
	uint8_t g_KeyVal = KEY_INVALID;
	BaseType_t xHigherPriorityTaskWoken;
	
	// 保存键值
	uint8_t //pe2 = LL_GPIO_IsInputPinSet(GPIOE, GPIO_PIN_2),
			pe3 = LL_GPIO_IsInputPinSet(GPIOB, GPIO_PIN_3), 
			pe4 = LL_GPIO_IsInputPinSet(GPIOB, GPIO_PIN_4), 
			pe5 = LL_GPIO_IsInputPinSet(GPIOB, GPIO_PIN_5); 
			//pe6 = LL_GPIO_IsInputPinSet(GPIOE, GPIO_PIN_6);

	// 记录是否按键唤醒
	Key_Wakeup = Wakeup_Sleeping;

	if(Wakeup_Sleeping)
	{
		SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);	
		//SystemClock_Config();
		delay_ms(10);
		Vcc_Enable();
		delay_ms(40);
		Wakeup_Sleeping = 0;
		
		// 判断是否为低电平，排除干扰
		if(/*!LL_GPIO_IsInputPinSet(GPIOE, GPIO_PIN_2) &&*/ LL_GPIO_IsInputPinSet(GPIOB, GPIO_PIN_3) 
			&& LL_GPIO_IsInputPinSet(GPIOB, GPIO_PIN_4) && LL_GPIO_IsInputPinSet(GPIOB, GPIO_PIN_5) 
			/*&& LL_GPIO_IsInputPinSet(GPIOE, GPIO_PIN_6)*/)
		{
			printf("\nWakeup by DISTURB2 ...\n");

			// 由干扰引起的按键中断，发信号休眠
			return;
		}

		printf("\n\nWake up by KEY.\n\n");
		
		// 采集数据
		Sample_NotifyFromISR();
	}

	// 防抖动，300ms以内的连续按键丢弃
	if((tick >= key_tick && tick - key_tick < 300) || (tick < key_tick && 0xFFFFFFFFul - key_tick + 1 + tick < 300))
		return;

	g_KeyVal = KEY_INVALID;	
//	if(pe2 != 0)
//	{
//		printf("\n----------- Key pe2 pressed -----------\n");
//		g_KeyVal = KEY_UP;
//	}
//	else 
	if(pe3 == 0)
	{
		//printf("\n----------- Key pe3 pressed -----------\n");
		g_KeyVal = KEY_UP;
		
	}
	else if(pe4 == 0)
	{
		//printf("\n----------- Key pe4 pressed -----------\n");
		g_KeyVal = KEY_FUNC;
	}
	else if(pe5 == 0)
	{
		//printf("\n----------- Key pe5 pressed -----------\n");
		//g_KeyVal = KEY_DOWN;
		g_KeyVal = KEY_SET;
	}
	/*
	else if(pe6 == 0)
	{
		//printf("\n----------- Key pe6 pressed -----------\n");
		g_KeyVal = KEY_SET;
	}
	*/
	if(g_KeyVal != KEY_INVALID)
	{
		key_tick = GetTickCount();

		// 重新计算时间
		Form_ResetTimer();

		// 不允许休眠
		LCD_Disabled = 0;

		// 加入缓冲
		LoopBuff_PutItem(&Key_TaskM, &g_KeyVal);
		// 发送消息给任务
		xSemaphoreGiveFromISR(Key_Semaphore, &xHigherPriorityTaskWoken);
	}	
}
