/*************************** (C) COPYRIGHT 2017 CXHY ****************************
 * 文件名  ：opto_sw_key.c
 * 描  述  ：光电开关驱动程序
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2017/03/06 
*********************************************************************************/
#include "opto_sw_key.h"
#include "delay.h"
#include "timer.h"
#include "device.h"
#include "data_typedef.h"

//红外光电开关
#define OPTO_KEY1_PORT				GPIOA						
#define OPTO_KEY1_PIN					GPIO_Pin_8

#define OPTO_KEY2_PORT				GPIOB					
#define OPTO_KEY2_PIN					GPIO_Pin_7

#define OPTO_KEY3_PORT				GPIOD					
#define OPTO_KEY3_PIN					GPIO_Pin_0

#define OPTO_KEY4_PORT				GPIOD				
#define OPTO_KEY4_PIN					GPIO_Pin_3


uint8_t optoKeyValue1 = 0;								//红外光电开关键值
uint8_t optoKeyValue2 = 0;								//红外光电开关键值
uint8_t optoKeyValue3 = 0;								//红外光电开关键值
uint8_t optoKeyValue4 = 0;								//红外光电开关键值
	
/*
***********************************************************************
*	函 数 名: OptoKeyInit
*	功能说明: 红外光电开关IO口初始化
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void OptoKeyInit(void)
{ 
 	GPIO_InitTypeDef GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA | 
													RCC_APB2Periph_GPIOB | 
													RCC_APB2Periph_GPIOD, ENABLE);		//使能PORTA时钟
	
	//第一路红外光电开关IO口配置
	GPIO_InitStructure.GPIO_Pin = OPTO_KEY1_PIN;			 				
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 		 		
	GPIO_Init(OPTO_KEY1_PORT, &GPIO_InitStructure);	
	
	//第二路红外光电开关IO口配置
	GPIO_InitStructure.GPIO_Pin = OPTO_KEY2_PIN;			 				
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 		 			
	GPIO_Init(OPTO_KEY2_PORT, &GPIO_InitStructure);	
	
	//第三路红外光电开关IO口配置
	GPIO_InitStructure.GPIO_Pin = OPTO_KEY3_PIN;			 				
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 		 		
	GPIO_Init(OPTO_KEY3_PORT, &GPIO_InitStructure);	
	
	//第四路红外光电开关IO口配置
	GPIO_InitStructure.GPIO_Pin = OPTO_KEY4_PIN;			 				
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 		 		
	GPIO_Init(OPTO_KEY4_PORT, &GPIO_InitStructure);	
}

/*
***********************************************************************
*	函 数 名: OptoKeysCanning
*	功能说明: 红外光电开关检测
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void OptoKeysCanning(void)
{
	static uint8_t key1_state = 0;
	static uint8_t key2_state = 0;
	
	//第1路红外光电开关检测
	switch (key1_state)
	{
		case 0x00:
			if(OPTO_KEY1 == 0)
			{
				key1_state = 0x01;
			}
			break;
			
		case 0x01:
			if(OPTO_KEY1 == 0)
			{
				optoKeyValue1 = 1;
			}else{
				optoKeyValue1 = 0;
				key1_state = 0x00;
			}
			break;
			
		default:
			key1_state = 0x00;
			break;
	}
	
	//第2路红外光电开关检测
	switch (key2_state)
	{
		case 0x00:
			if(OPTO_KEY2 == 0)
			{
				key2_state = 0x01;
			}
			break;
			
		case 0x01:
			if(OPTO_KEY2 == 0)
			{
				optoKeyValue2 = 1;
			}else{
				optoKeyValue2 = 0;
				key2_state = 0x00;
			}
			break;
			
		default:
			key2_state = 0x00;
			break;
	}
}

/*
***********************************************************************
*	函 数 名: BottleScanning
*	功能说明: 瓶子投放扫描检测
*	形    参：无
*	返 回 值: 返回对应开关的键值
***********************************************************************
*/
void BottleScanning(void)
{
	static uint8_t bottleType = 0;
	static uint16_t count;
	static uint8_t testStatus = 0x00;
	
	static timer timerOut;
	static timer waitingTimer;
	static timer wrongOperationTimer;
	
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&timerOut, 4);
		timer_set(&waitingTimer, CLOCK_SECOND*5);
		timer_set(&wrongOperationTimer, CLOCK_SECOND*3);
	}
	
	switch(testStatus)
	{
		case 0x00:
			if((OPTO_KEY3 == 1) && (OPTO_KEY4 == 0))
			{
// 				printf("\r\n错误操作\r\n");
// 				printf("%d %d\r\n", OPTO_KEY3, OPTO_KEY4);
				timer_restart(&wrongOperationTimer);
				testStatus = 0x10;
				break;
			}
			if((OPTO_KEY3 == 0) && (OPTO_KEY4 == 1))				//检测到开始投瓶
			{
// 				printf("\r\n开始投瓶\r\n");
// 				printf("%d %d\r\n", OPTO_KEY3, OPTO_KEY4);
				timer_restart(&waitingTimer);
				testStatus = 0x01;
			}
			break;
			
		case 0x01:		//等待瓶子经过第一个检测探头
			if(timer_expired(&waitingTimer))
			{
				printf("\r\n0x01投放超时返回\r\n");
				testStatus = 0x00;
				break;
			}
// 			if((OPTO_KEY3 == 0) || (OPTO_KEY4 == 0))
// 			{
// 				printf("%d %d\r\n", OPTO_KEY3, OPTO_KEY4);
// 			}
			if((OPTO_KEY3 == 0) && (OPTO_KEY4 == 0))				//两个探头同时检测到瓶子说明为大瓶子
			{
				bottleType = 1;																									//标志为大瓶子
			}
			if((OPTO_KEY3 == 1) && (OPTO_KEY4 == 0))				//等待瓶子完全通过第一个探头
			{
				timer_restart(&waitingTimer);
				testStatus = 0x02;
				break;
			}
			break;
			
		case 0x02:		//检测瓶子完全通过两个探头（说明已经完整通过了通道）
			if(timer_expired(&waitingTimer))
			{
				printf("\r\n0x02投放超时返回\r\n");
				testStatus = 0x00;
				break;
			}
			
// 			if((OPTO_KEY3 == 0) || (OPTO_KEY4 == 0))
// 			{
// 				printf("%d %d\r\n", OPTO_KEY3, OPTO_KEY4);
// 			}
			if((OPTO_KEY3 == 0) && (OPTO_KEY4 == 0))				//两个探头同时检测到瓶子说明为大瓶子
			{
				bottleType = 1;																									//标志为大瓶子
			}
			if((OPTO_KEY3 == 1) && (OPTO_KEY4 == 1))
			{
				timer_restart(&timerOut);
				timer_restart(&waitingTimer);
				testStatus = 0x03;
				break;
			}
			break;
			
		case 0x03:		//判断已经完全通过检测通道（相隔一小段时间后都没有检测到瓶子说明已经投放成功）
			if(timer_expired(&timerOut))
			{
				if(timer_expired(&waitingTimer))
				{
					printf("\r\n0x03投放超时返回\r\n");
					testStatus = 0x00;
					break;
				}
			
				if((OPTO_KEY3 == 1) || (OPTO_KEY4 == 1))			//瓶子已经完全离开通道
				{
					printf("\r\n投放成功！！！\r\n");
					beep_shortBeepMark = 1;
					
					//目前只按小瓶子来计算
// 					if(bottleType)
// 					{
// 						bigBottleCount++;	
// 					}else{
// 						smallBottleCount++;
// 					}
					
					smallBottleCount++;

// 					printf("\r\n大瓶子（数量：%d），小瓶子（数量：%d）\r\n", bigBottleCount, smallBottleCount);
					bottleType = 0;
					testStatus = 0x00;
					break;
				}
			}
			break;
			
		case 0x10:		//错误操作
			if(timer_expired(&wrongOperationTimer))
			{
				testStatus = 0x00;
				printf("\r\nerror return!\r\n");
				break;
			}
// 			if((OPTO_KEY3 == 0) || (OPTO_KEY4 == 0))
// 			{
// 				printf("%d %d\r\n", OPTO_KEY3, OPTO_KEY4);
// 			}
			if((OPTO_KEY3 == 0) && (OPTO_KEY4 == 1))
			{
				testStatus = 0x11;
				timer_restart(&waitingTimer);
				break;
			}
			break;
			
		case 0x11:	
			if(timer_expired(&waitingTimer))
				{
					printf("\r\n0x11time out return!\r\n");
					testStatus = 0x00;
					break;
				}
// 			if((OPTO_KEY3 == 0) || (OPTO_KEY4 == 0))
// 			{
// 				printf("%d %d\r\n", OPTO_KEY3, OPTO_KEY4);
// 			}
			if((OPTO_KEY3 == 1) && (OPTO_KEY4 == 1))
			{
				timer_restart(&timerOut);
				timer_restart(&waitingTimer);
				testStatus = 0x12;
				break;
			}
			break;
		
		case 0x12:
			if(timer_expired(&timerOut))
			{
				if(timer_expired(&waitingTimer))
				{
					printf("\r\n0x12time out return!\r\n");
					testStatus = 0x00;
					break;
				}
				
				if((OPTO_KEY3 == 1) || (OPTO_KEY4 == 1))
				{
					printf("\r\nwarning!\r\n");
					beep_warningBeepMark = 1;							//标志警告声
					
					if(smallBottleCount > 0)
					{
						smallBottleCount--;
					}
					testStatus = 0x00;
					break;
				}
			}
			break;
		default: break;
	}
}

/*
***********************************************************************
*	函 数 名: OptoKeysTest
*	功能说明: 红外光电开关测试
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void OptoKeysTest(void)
{
	static uint8_t optoKeyStatus1 = 0;
	static uint8_t optoKeyStatus2 = 0;
	
	if(optoKeyStatus1 != optoKeyValue1)
	{
		optoKeyStatus1 = optoKeyValue1;
		
		if(optoKeyValue1)
		{
			printf("\r\n红外光电开关1触发\r\n");
		}else{
			printf("\r\n红外光电开关1恢复正常\r\n");
		}
	}
	
	if(optoKeyStatus2 != optoKeyValue2)
	{
		optoKeyStatus2 = optoKeyValue2;
		
		if(optoKeyValue2)
		{
			printf("\r\n红外光电开关2触发\r\n");
		}else{
			printf("\r\n红外光电开关2恢复正常\r\n");
		}
	}
}

/******************** (C) COPYRIGHT 2018 Ping *****END OF FILE*******************/
