#include"common.h"
#include "drv_io.h"
#include "drv_usart.h"
#include "drv_usart_2.h"
#include "app.h"
#include "app_rs485_1.h"
#include "app_rs485_2.h"
#include "drv_can.h"
#include "app_adas.h"
#include "measure_vol.h"
#include "app_can.h"
#include "hardware_test.h"
#include "measure_temprature.h"
#include "app_end_ctr.h"

static uint8_t app_rs485_buf[TX_BUFFER_SIZE];
uint8_t ht_mode = 0;
uint8_t where_from = FROM_USART_1;
uint8_t over_12V = 0;
const uint16_t ht_flash = 0x2323;
//#define ht_flash  (0x2323)
DELAY_COMMON  HT_Reboot;

extern uint8_t work_normal;

#ifdef CONFIG_CAN_IAP
extern void qws_iap_write_magic(uint32_t magic);
#endif

void HT_Reboot_Timeout(void)
{
	if(HT_Reboot.set)
	{
		if(++HT_Reboot.count > 3000)
		{
			memset(&HT_Reboot,0x00,sizeof(HT_Reboot));
			g_event |= DEVICE_REBOOT_EVENT;
		}
	}
}

void HT_Flash_flag_clear(void)
{
	fmc_flag_clear(FMC_FLAG_BANK0_PGERR | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_END);
}
uint8_t Check_HT_Flash(void)
{
	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
	uint32_t address = 0x08000000 + (capacity - HARD_TEST_FLASH_ADDRESS);
	uint16_t flag = REG16(address);

	if (REG16(address) == ht_flash) 
		return 1;
	else
		return 0;
}

void Writer_HT_Flash(uint8_t flag)
{
	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
	uint32_t address = 0x08000000 + (capacity - HARD_TEST_FLASH_ADDRESS);
	
	uint16_t df_value ;

	if(flag)
	{
		df_value = ht_flash;
		HT_Reboot.set = 1;
		HT_Reboot.count = 0;
	}
	else
		df_value = 0xFFFF;
	
	fmc_unlock();

	HT_Flash_flag_clear();
	fmc_page_erase(address);

	
	HT_Flash_flag_clear();
	fmc_halfword_program(address,df_value);
	HT_Flash_flag_clear();
	
	fmc_lock();

	
}

uint8_t HT_Frame_CRC(uint8_t*data,uint8_t len)
{
	uint8_t i,crc = 0;

	for(i = 0;i<len;i++)
		crc += data[i];

	return crc;
}

int8_t HT_Handle_CMD( uint8_t *data)
{
	HT_FRAME * ht_frame = (HT_FRAME *)data;
	uint8_t temp;

	do
	{
		if(NULL == data)
		{
			return 0;
		}

		
		if(ht_frame->ht_dir != 1)
			break;

		//CRC 
		temp = ht_frame->ht_crc;
		ht_frame->ht_crc = 0;
		if(temp != HT_Frame_CRC(data,ht_frame->ht_len))
		{
			break;
		}

		temp = sizeof(HT_FRAME);
	
		//handle frame
		switch(ht_frame->ht_cmd)
		{
			case HT_IDRA:
				S21_ENABLE(1);
				break;
				
			case HT_12V:
				if(data[temp] == 1)
					Enable_12V(1);
				else if(data[temp] == 2)
					Enable_12V(0);
				else
					return 0;
				break;
				
			case HT_CAN:
				if(data[temp] == 1)
				{
					Can_Power_Enable(1);
					work_normal = 1;
				}
				else if(data[temp] == 2)
				{
					Can_Power_Enable(0);
					work_normal = 0;
				}
				else
					return 0;
				break;
				
			case HT_QD:
				if(data[temp] == 1)
					QD_Enable(1);
					//QD_Enable_From(1,6);
				else if(data[temp] == 2)
					QD_Enable(0);
					//QD_Enable_From(0,7);
				else
					return 0;
				break;
				
			case HT_ACC:
				break;


			case HT_S_P:
				break;

			case HT_LIGHT:
				break;

			case HT_INPUT:
				break;

			case HT_LOCK:
				break;
				
			case HT_XL:
				break;

			case HT_CHARGER:
				break;
				
			case HT_TEMP:
				break;

			case HT_ADAS:
				break;
				
			default:return 0;
		}

		
		return 1;
		
	}while(0);

	return 0;
	
}

int8_t HT_Rsp_CMD(uint8_t *buf)
{
	HT_FRAME * ht_frame = (HT_FRAME *)buf;
	uint8_t len;
	
	if(NULL == buf)
	{
		return 0;
	}

	switch(ht_frame->ht_cmd)
	{
		case HT_IDRA:
			len = sizeof(HT_FRAME);
			buf[len++] = 0; 
			break; 
		case HT_12V:
			len = sizeof(HT_FRAME);
			buf[len++] = 0; 
			break; 
		case HT_CAN:
			len = sizeof(HT_FRAME);
			buf[len++] = 0; 
			break; 

		case HT_QD:
			len = sizeof(HT_FRAME);
			buf[len++] = !QD_Dect(); 
			break;

		case HT_ACC:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				FL_Enable(1);
				buf[len++] = 0; 
			}
			else if(buf[len] == 2)
			{
				over_12V = 0;
				gpio_bit_write(GPIOC,GPIO_PIN_15,SET);
				buf[len++] = gpio_input_bit_get(GPIOD,GPIO_PIN_0);
			}
			else if(buf[len] == 3)
			{
				buf[len++] = over_12V;
				over_12V = 0;
			}
			else if(buf[len] == 4)
			{
				gpio_bit_write(GPIOC,GPIO_PIN_15,RESET);
				buf[len++] = gpio_input_bit_get(GPIOD,GPIO_PIN_0);
			}
			else if(buf[len] == 5)
			{
				FL_Enable(0);
				buf[len++] = 0; 
			}
			else
				return 0;
			break;

		case HT_S_P:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				S11_ENABLE(0);
				S21_ENABLE(0);
				SS__ENABLE(0);
				delay_1ms(100);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_1);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_2);
				uint32_t vol = Measure_Vol();
				buf[len++] = (uint8_t)(vol >> 0);
				buf[len++] = (uint8_t)(vol >> 8);
				buf[len++] = (uint8_t)(vol >> 16);
				buf[len++] = (uint8_t)(vol >> 24);
			}
			else if(buf[len] == 2)
			{
				if(buf[len + 1] == 1)
				{
					S21_ENABLE(1);
					buf[len++] = 0;
				}
				else if(buf[len + 1] == 2)
				{
					delay_1ms(100);
					uint32_t vol = Measure_Vol();
					buf[len++] = (uint8_t)(vol >> 0);
					buf[len++] = (uint8_t)(vol >> 8);
					buf[len++] = (uint8_t)(vol >> 16);
					buf[len++] = (uint8_t)(vol >> 24);
				}
				else if(buf[len + 1] == 3)
				{
					S21_ENABLE(0);
					buf[len++] = 0;
				}

				
			}
			else if(buf[len] == 3)
			{
				delay_1ms(100);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_1);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_2);
				uint32_t vol = Measure_Vol();
				buf[len++] = (uint8_t)(vol >> 0);
				buf[len++] = (uint8_t)(vol >> 8);
				buf[len++] = (uint8_t)(vol >> 16);
				buf[len++] = (uint8_t)(vol >> 24);
			}
			else if(buf[len] == 4)
			{
				if(buf[len + 1] == 1)
				{
					FL_Enable(1);
					delay_1ms(10);
					S11_ENABLE(1);
					buf[len++] = 0;
				}
				else if(buf[len + 1] == 2)
				{
					delay_1ms(100);
					uint32_t vol = Measure_Vol();
					buf[len++] = (uint8_t)(vol >> 0);
					buf[len++] = (uint8_t)(vol >> 8);
					buf[len++] = (uint8_t)(vol >> 16);
					buf[len++] = (uint8_t)(vol >> 24);
				}
				else if(buf[len + 1] == 3)
				{
					FL_Enable(0);
					S11_ENABLE(0);
					buf[len++] = 0;
				}
				
			}
			else if(buf[len] == 5)
			{
				delay_1ms(100);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_1);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_2);
				uint32_t vol = Measure_Vol();
				buf[len++] = (uint8_t)(vol >> 0);
				buf[len++] = (uint8_t)(vol >> 8);
				buf[len++] = (uint8_t)(vol >> 16);
				buf[len++] = (uint8_t)(vol >> 24);
			}
			else if(buf[len] == 6)
			{
				if(buf[len + 1] == 1)
				{
					SS__ENABLE(1);
					buf[len++] = 0;
				}
				else if(buf[len + 1] == 2)
				{
					delay_1ms(100);
					uint32_t vol = Measure_Vol();
					buf[len++] = (uint8_t)(vol >> 0);
					buf[len++] = (uint8_t)(vol >> 8);
					buf[len++] = (uint8_t)(vol >> 16);
					buf[len++] = (uint8_t)(vol >> 24);
				}
				else if(buf[len + 1] == 3)
				{
					SS__ENABLE(0);
					buf[len++] = 0;
				}
				
			}
			else if(buf[len] == 7)
			{
				FL_Enable(1);
				delay_1ms(10);
				S11_ENABLE(1);
				S21_ENABLE(1);
				SS__ENABLE(1);
				
				buf[len++] = 0;
			}
			else if(buf[len] == 8)
			{
				
				SS__ENABLE(0);
				
				buf[len++] = 0;
			}
			else if(buf[len] == 9)
			{
				
				S21_ENABLE(0);
				
				buf[len++] = 0;
			}
			else
				return 0;
			break;

		case HT_LIGHT:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				Right_Light_Enable(0);
				Tail_Light_Enable(0);
				Left_Light_Enable(1);
				Carpet_Light_Enable(1);
				buf[len++] = 0; 
			}
			else if(buf[len] == 2)
			{
				Left_Light_Enable(0);
				Carpet_Light_Enable(0);
				Right_Light_Enable(1);
				Tail_Light_Enable(1);
				buf[len++] = 0;
			}
			else if(buf[len] == 3)
			{
				Right_Light_Enable(0);
				Tail_Light_Enable(0);
				Left_Light_Enable(0);
				Carpet_Light_Enable(0);
				buf[len++] = 0;
			}
			else
				return 0;
			break;

		case HT_INPUT:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				buf[len++] = Side_Stay_Dect();
				buf[len++] = !Soak_Dect();
				buf[len++] = Sitting_Dect(); 
			}
			else if(buf[len] == 2)
			{
			
				buf[len++] = Side_Stay_Dect();
				buf[len++] = !Soak_Dect();
				buf[len++] = Sitting_Dect(); 
			}
			else
				return 0;
			break;

		case HT_LOCK:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				Lock_Enable(1);
				buf[len++] = 0;
			}
			else if(buf[len] == 2)
			{
				Lock_Enable(0);
				buf[len++] = 0;
			}
			else
				return 0;
			break;

		case HT_XL:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				xl_count = 0;
				delay_1ms(100);
				if(xl_count)
					buf[len++] = 1;
				else
					buf[len++] = 0;
			}
			else if(buf[len] == 2)
			{
				xl_count = 0;
				delay_1ms(100);
				if(xl_count)
					buf[len++] = 1;
				else
					buf[len++] = 0;
			}
			else
				return 0;
			break;

		case HT_CHARGER:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				CHARG_PROTECT_OPEN(1);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_4);
			}
			else if(buf[len] == 2)
			{
				CHARG_PROTECT_OPEN(0);
				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_4);
			}
			else
				return 0;
			break;

		case HT_TEMP:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				getTemperature();
				buf[len++] = (uint8_t)(ctr_temperature[0]);
				buf[len++] = (uint8_t)(ctr_temperature[1]);
			}
			else
				return 0;
			break;

		case HT_ADAS:
			len = sizeof(HT_FRAME);
			if(buf[len] == 1)
			{
				ADAS_Enable(1);
				
				buf[len++] = 0;
			
			}
			else if(buf[len] == 2)
			{
				buf[len++] = (uint8_t)(ju_li_1 >> 0);
				buf[len++] = (uint8_t)(ju_li_1 >> 8);
				buf[len++] = (uint8_t)(ju_li_2 >> 0);
				buf[len++] = (uint8_t)(ju_li_2 >> 8);
			}
			else
				return 0;
			break;
			
		default:break;
	}

	// ÌîÖ¡Í·
	ht_frame->ht_len = len;
	ht_frame->ht_dir = 0;
	ht_frame->ht_crc = 0;
	ht_frame->ht_crc = HT_Frame_CRC(buf,ht_frame->ht_len);
	
	return 1;

}

int8_t HT_Handle_RS485_Data(uint8_t from)
{
	uint8_t len ;
	
	if(from == FROM_USART_1)
	{
		len = Get_RS485_Data(app_rs485_buf,sizeof(app_rs485_buf));
	}
	else if(from == FROM_USART_2)
	{
		len = Get_RS485_2_Data(app_rs485_buf,sizeof(app_rs485_buf));
	}
	else
		return 0;
	
	where_from = from;
	if(len != app_rs485_buf[0])
	{
		return 0;

	}

	if(!HT_Handle_CMD(app_rs485_buf))
		return 0;

	if(!HT_Rsp_CMD(app_rs485_buf))
		return 0;

	if(from == FROM_USART_1)
	{
		if(!Send_Data_RS485(app_rs485_buf,app_rs485_buf[0]))
			return 0;
	}
	else if(from == FROM_USART_2)
	{
		if(!Send_Data_2_RS485(app_rs485_buf,app_rs485_buf[0]))
			return 0;
	}

	return 1;
}



void HT_Main(void)
{
	if(Repair_Key_Dect() && !Check_HT_Flash())
		return;

#ifdef CONFIG_CAN_IAP
	qws_iap_write_magic(0x11223344);
#endif

	Writer_HT_Flash(0);

	ht_mode = 1;

	memset(&send_delay,0x00,sizeof(send_delay));
	
	
	for(;;)
	{
		Check_Can_Poll();
		
		Handle_Can_Data();

		if(g_event & RS485_RECEIVE_END_EVENT)
		{
			
			if(HT_Handle_RS485_Data(FROM_USART_1) == 0)
			{
				// output fail
				
				;
			}
			g_event &= ~RS485_RECEIVE_END_EVENT;
		}
	
		if(g_event & RS485_2_RECEIVE_END_EVENT)
		{
			
			if(HT_Handle_RS485_Data(FROM_USART_2) == 0)
			{
				// output fail
				
				;
			}
			g_event &= ~RS485_2_RECEIVE_END_EVENT;
		}


		if(g_event & ADAS_PWM_1_TIMEOUT_EVENT)
		{
			ADAS_PWM_1_Enable();
			
			g_event &= ~ADAS_PWM_1_TIMEOUT_EVENT;
			
		}

		if(g_event & ADAS_PWM_2_TIMEOUT_EVENT)
		{
			ADAS_PWM_2_Enable();
			
			g_event &= ~ADAS_PWM_2_TIMEOUT_EVENT;
			
		}

		if(g_event & ADAS_MEAS_1_FINISH_EVENT)
		{
			ADAS_Measure_Finish_Ju_Li_1();

			ADAS_Self_Send_Up();
			
			g_event &= ~ADAS_MEAS_1_FINISH_EVENT;
			
		}

		if(g_event & ADAS_MEAS_2_FINISH_EVENT)
		{
			ADAS_Measure_Finish_Ju_Li_2();
			
			g_event &= ~ADAS_MEAS_2_FINISH_EVENT;
			
		}


		
	}
}

