#include "HW_Config.h"
#include "uart_lp_test_drv.h"
#include "user_norflash.h"
#include "CnCpp.h"
#include "HW_test_task.h"
#include "internal_flash.h"

#define TEST_RX_TIMEOUT 50

#define NORFLASH_GBK_ADDR 	0x009C0000
#define SDRAM_GBK_ADDR 			0xC0600000

#define SIZE_OF_BYTE_GBK_LIB 	(23940*24*3)
#define SIZE_OF_PAGE_GBK_LIB 	6734
#define SIZE_OF_64K_GBK_LIB		27

#define dFlashGBKChipX		(0)

TdataType load_data;

typedef union{
	unsigned char D8[264];
	unsigned int D32[66];
	struct{
		unsigned char head;
		unsigned char cmd;
		unsigned short len;
		unsigned char data[260];
	}prm;
}Tcom_gbk_pkg_gbk;

Tcom_gbk_pkg_gbk * gbk_rx_pkg;
Tcom_gbk_pkg_gbk * gbk_tx_pkg;

unsigned char test_uart_tx[64];
unsigned char test_uart_rx[272];

unsigned int rx_state = 0;
unsigned int rx_starttime_flag = 0;
unsigned int rx_timecount = 0;

static unsigned int rpy_usb_state = 0;
static unsigned int rpy_usb_state_tick = 0;

void config_app_handle(void);
void gbk_download_handle(void);

unsigned int test_tx_is_busy(void)//1:is busy 0:no busy
{
	if(!get_uart_tx_complete_delay_flag(TEST_UART))return 1;
	
	return 0;
}

void set_test_tx_data(unsigned char * pdata, unsigned int len)//fec¸ñÊ½£¬¼ÓÉÏºóÃæcrc 2byte Óëend
{
	unsigned int i = 0;
	unsigned short crc_value = 0;
	
	uart_load_txbuf(TEST_UART, pdata, len);
	
	crc_value = crc16_data(uart_info_8bit[TEST_UART].tx_buf, len);
	uart_info_8bit[TEST_UART].tx_buf[len] = (crc_value&0xFF);
	uart_info_8bit[TEST_UART].tx_buf[len+1] = ((crc_value&0xFF00)>>8);
	
	uart_info_8bit[TEST_UART].tx_buf[len+2] = TEST_UART_END;
	uart_info_8bit[TEST_UART].tx_len = len+3;
	
	uart_tx_trigger(TEST_UART);
}
	
void test_rx_timeout_tick(void)//1ms in irq
{
	if(rx_starttime_flag){
		rx_timecount++;
		if(rx_timecount > 55){//57600 272byte:48ms
			rx_state = 0;
			rx_starttime_flag = 0;
			rx_timecount = 0;
		}
	}
	
	if(rpy_usb_state){
		if(rpy_usb_state_tick > 3000){
			rpy_usb_state_tick = 0;
			rpy_usb_state = 0;
			
			if(UsbConfigGetState()){
				gbk_tx_pkg->prm.data[1] = 1;
			}else{
				gbk_tx_pkg->prm.data[1] = 0;
			}
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = 0xA0;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = 0x22;
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else{
			rpy_usb_state_tick++;
		}
	}else{
		rpy_usb_state_tick = 0;
	}
}

void test_rx_irq(void)
{
	unsigned short cc;
	
	if(LL_USART_IsActiveFlag_RXNE(LPUART1))
	{
		cc = LL_USART_ReceiveData8(LPUART1);
		switch(rx_state){
			case 0 :
								if(TEST_UART_HEAD == cc){
									uart_info_8bit[TEST_UART].rx_index = 0;
									uart_info_8bit[TEST_UART].rx_buf[uart_info_8bit[TEST_UART].rx_index] = cc;
									uart_info_8bit[TEST_UART].rx_len = UART_RX_BUF_MAX;
									rx_starttime_flag = 1;
									rx_state++;
								}
								break;
								
			case 1:
								uart_info_8bit[TEST_UART].rx_index++;
								uart_info_8bit[TEST_UART].rx_buf[uart_info_8bit[TEST_UART].rx_index] = cc;
								if(3 == uart_info_8bit[TEST_UART].rx_index){
									if(uart_info_8bit[TEST_UART].rx_buf[1] > 0x80){
										uart_info_8bit[TEST_UART].rx_len = uart_info_8bit[TEST_UART].rx_buf[3];
										uart_info_8bit[TEST_UART].rx_len<<=8;
										uart_info_8bit[TEST_UART].rx_len |= uart_info_8bit[TEST_UART].rx_buf[2];
										uart_info_8bit[TEST_UART].rx_len +=7;
										if(uart_info_8bit[TEST_UART].rx_len > (260+8)){
											rx_state = 0;
											rx_starttime_flag = 0;
											rx_timecount = 0;
										}else{
											rx_state++;
										}
									}else{
										uart_info_8bit[TEST_UART].rx_len = 7 + cc;
										if(uart_info_8bit[TEST_UART].rx_len > 128){
											rx_state = 0;
											rx_starttime_flag = 0;
											rx_timecount = 0;
										}else{
											rx_state++;
										}
									}
								}else
								if(uart_info_8bit[TEST_UART].rx_index > 3){
									rx_state = 0;
									rx_starttime_flag = 0;
									rx_timecount = 0;
								}
								break;
			
			case 2:
								uart_info_8bit[TEST_UART].rx_index++;
								uart_info_8bit[TEST_UART].rx_buf[uart_info_8bit[TEST_UART].rx_index] = cc;
								if(((uart_info_8bit[TEST_UART].rx_len - 1) == uart_info_8bit[TEST_UART].rx_index)&&(rx_timecount < TEST_RX_TIMEOUT)&&(cc == TEST_UART_END)){
									uart_info_8bit[TEST_UART].rx_complete = 1;
									rx_state = 0;
									rx_starttime_flag = 0;
									rx_timecount = 0;
								}else
								if(uart_info_8bit[TEST_UART].rx_index > uart_info_8bit[TEST_UART].rx_len){
									rx_state = 0;
									rx_starttime_flag = 0;
									rx_timecount = 0;
								}
								break;
			
			default:
								rx_state = 0;
								rx_starttime_flag = 0;
								rx_timecount = 0;
								break;
		}
	}
}

void lpuart_rx_task(void)
{
	if(uart_info_8bit[TEST_UART].rx_complete){
		uart_info_8bit[TEST_UART].rx_complete = 0;
		
		//LoadDebugViaFECTest(uart_info_8bit[TEST_UART].rx_buf);
		if(!check_crc(uart_info_8bit[TEST_UART].rx_buf,(uart_info_8bit[TEST_UART].rx_len-1))){
			if(uart_info_8bit[TEST_UART].rx_buf[1] < 0x80){
				//-----------------config app handle------------------
				config_app_handle();
			}else{
				//-----------------gbk download handle----------------
				gbk_download_handle();
			}
		}
	}
}

void uart_test_task(void)
{
	lpuart_rx_task();
}

void gbk_nor_load_to_sdram(void)
{
	unsigned int x,y;
	for(y = 0;y < SIZE_OF_PAGE_GBK_LIB;y++){
		nor_read_page(0, (NORFLASH_GBK_ADDR + (y * 256)), load_data.D8);
		for(x = 0;x < 64;x++){
			*(volatile unsigned int *)(SDRAM_GBK_ADDR + (y * 256) + (x * 4)) = load_data.D32[x];
		}
	}
}

void gbk_download_handle(void)
{
	unsigned int i,aFlashState;
	
	gbk_tx_pkg = (Tcom_gbk_pkg_gbk *)test_uart_tx;
	gbk_rx_pkg = (Tcom_gbk_pkg_gbk *)uart_info_8bit[TEST_UART].rx_buf;
	
	if(0x88 == gbk_rx_pkg->prm.cmd){
		gbk_tx_pkg->prm.head = TEST_UART_HEAD;
		gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
		gbk_tx_pkg->prm.len = 0;
		set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
	}else
	if(0x90 == gbk_rx_pkg->prm.cmd){
		for(i=0;i<SIZE_OF_64K_GBK_LIB;i++){
			nor_erase_sector_64k(dFlashGBKChipX, (NORFLASH_GBK_ADDR+(i*64*1024)));
			do{
				HAL_Delay(2);
				aFlashState = nor_get_busy_state(dFlashGBKChipX);
			}while(aFlashState);
		}
		
		gbk_tx_pkg->prm.head = TEST_UART_HEAD;
		gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
		gbk_tx_pkg->prm.len = 4;
		gbk_tx_pkg->prm.data[0] = 0xAA;
		gbk_tx_pkg->prm.data[1] = 0;
		gbk_tx_pkg->prm.data[2] = 0;
		gbk_tx_pkg->prm.data[3] = 0;
		
		set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
	}else
	if(0x91 == gbk_rx_pkg->prm.cmd){
		nor_write_page(dFlashGBKChipX,(NORFLASH_GBK_ADDR + (gbk_rx_pkg->D32[1] * 256)),&gbk_rx_pkg->prm.data[4]);
		do{
			HAL_Delay(2);
			aFlashState = nor_get_busy_state(dFlashGBKChipX);
		}while(aFlashState);
		
		gbk_tx_pkg->prm.head = TEST_UART_HEAD;
		gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
		gbk_tx_pkg->prm.len = 4;
		gbk_tx_pkg->prm.data[0] = 0xAA;
		gbk_tx_pkg->prm.data[1] = 0;
		gbk_tx_pkg->prm.data[2] = 0;
		gbk_tx_pkg->prm.data[3] = 0;
		
		set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
	}else
	//-------------------------------------------------test(²âÊÔ°å×Ó)--------------------------------------------------
	if(0xA0 == gbk_rx_pkg->prm.cmd){
		if(0x20 == gbk_rx_pkg->prm.data[0]){//²âÊÔuart1-7
			hw_test_mode = 1;
			hw_test_init();
			
			gbk_tx_pkg->prm.data[1] = (unsigned char)hw_uart_test_all() + 1;
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x21 == gbk_rx_pkg->prm.data[0]){//ÍË³ö²âÊÔ
			hw_test_mode = 0;
			hw_test_deinit();
			
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			gbk_tx_pkg->prm.data[1] = 1;
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x22 == gbk_rx_pkg->prm.data[0]){//¼ì²âUÅÌ
			if(hw_test_mode){		
				if(usb_is_host){
					if(UsbConfigGetState()){
						gbk_tx_pkg->prm.data[1] = 1;
					}else{
						gbk_tx_pkg->prm.data[1] = 0;
					}
					gbk_tx_pkg->prm.head = TEST_UART_HEAD;
					gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
					gbk_tx_pkg->prm.len = 2;
					gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
						
					set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
				}else{
					usb_device_to_host();
					rpy_usb_state = 1;
				}
			}else{
				usb_host_to_device();
				gbk_tx_pkg->prm.head = TEST_UART_HEAD;
				gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
				gbk_tx_pkg->prm.len = 2;
				gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
				gbk_tx_pkg->prm.data[1] = 0x55;
				
				set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
			}
		}else
		if(0x24 == gbk_rx_pkg->prm.data[0]){//²âÊÔÏÔÊ¾ÆÁ
			if(hw_test_mode){
				hw_lcd_test();
			}
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			gbk_tx_pkg->prm.data[1] = hw_test_mode;
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x25 == gbk_rx_pkg->prm.data[0]){//²âÊÔnor flash¶ÁÐ´
			if(hw_test_mode){
				if(hw_nor_flash_test()){
					gbk_tx_pkg->prm.data[1] = 0;
				}else{
					gbk_tx_pkg->prm.data[1] = 1;
				}
			}else{
				gbk_tx_pkg->prm.data[1] = 0x55;
			}
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x26 == gbk_rx_pkg->prm.data[0]){//²âÊÔeeprom¶ÁÐ´
			if(hw_test_mode){
				if(hw_eeprom_test()){
					gbk_tx_pkg->prm.data[1] = 0;
				}else{
					gbk_tx_pkg->prm.data[1] = 1;
				}
			}else{
				gbk_tx_pkg->prm.data[1] = 0x55;
			}
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x27 == gbk_rx_pkg->prm.data[0]){//²âÊÔsdram¶ÁÐ´
			if(hw_test_mode){
				if(hw_sdram_test()){
					gbk_tx_pkg->prm.data[1] = 0;
				}else{
					gbk_tx_pkg->prm.data[1] = 1;
				}
			}else{
				gbk_tx_pkg->prm.data[1] = 0x55;
			}
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x28 == gbk_rx_pkg->prm.data[0]){//²âÊÔprint
			if(hw_test_mode){
				hw_print_test();
				gbk_tx_pkg->prm.data[1] = 1;
			}else{
				gbk_tx_pkg->prm.data[1] = 0x55;
			}
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x29 == gbk_rx_pkg->prm.data[0]){//²âÊÔ¼ÌµçÆ÷
			if(hw_test_mode){
				hw_relay_test();
				gbk_tx_pkg->prm.data[1] = 1;
			}else{
				gbk_tx_pkg->prm.data[1] = 0x55;
			}
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}else
		if(0x2A == gbk_rx_pkg->prm.data[0]){//²âÊÔuart1-7 ³ýuart6
			hw_test_mode = 1;
			hw_test_init();
			
			gbk_tx_pkg->prm.data[1] = (unsigned char)hw_uart_test() + 1;
			gbk_tx_pkg->prm.head = TEST_UART_HEAD;
			gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
			gbk_tx_pkg->prm.len = 2;
			gbk_tx_pkg->prm.data[0] = gbk_rx_pkg->prm.data[0];
			
			set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
		}
	}else
	//-------------------------------------------------¶ÁÐ´±àÂë--------------------------------------------------
	if(0xB0 == gbk_rx_pkg->prm.cmd){
		if((gbk_rx_pkg->prm.data[0] > 0)&&(gbk_rx_pkg->prm.data[0] < 255)){
		factory_prm.ctl_type = gbk_rx_pkg->prm.data[0];
		for(i=0;i<7;i++)factory_prm.pid[i] = gbk_rx_pkg->prm.data[i+4];
		factory_prm.pid[7] = 0;

		write_factory_prm();

		gbk_tx_pkg->prm.data[0] = 1;
		}else{
		gbk_tx_pkg->prm.data[0] = 0;
		}
		gbk_tx_pkg->prm.head = TEST_UART_HEAD;
		gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
		gbk_tx_pkg->prm.len = 1;
		set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
	}else
	if(0xB1 == gbk_rx_pkg->prm.cmd){
		gbk_tx_pkg->prm.head = TEST_UART_HEAD;
		gbk_tx_pkg->prm.cmd = gbk_rx_pkg->prm.cmd;
		gbk_tx_pkg->prm.len = 16;
		gbk_tx_pkg->prm.data[0] = factory_prm.ctl_type & 0xFF;
		gbk_tx_pkg->prm.data[1] = 0;
		gbk_tx_pkg->prm.data[2] = 0;
		gbk_tx_pkg->prm.data[3] = 0;
		gbk_tx_pkg->prm.data[4] = factory_prm.pid[0];
		gbk_tx_pkg->prm.data[5] = factory_prm.pid[1];
		gbk_tx_pkg->prm.data[6] = factory_prm.pid[2];
		gbk_tx_pkg->prm.data[7] = factory_prm.pid[3];
		gbk_tx_pkg->prm.data[8] = factory_prm.pid[4];
		gbk_tx_pkg->prm.data[9] = factory_prm.pid[5];
		gbk_tx_pkg->prm.data[10] = factory_prm.pid[6];
		gbk_tx_pkg->prm.data[11] = 0;
		gbk_tx_pkg->prm.data[12] = 0;
		gbk_tx_pkg->prm.data[13] = 0;
		gbk_tx_pkg->prm.data[14] = 0;
		gbk_tx_pkg->prm.data[15] = 0;
		set_test_tx_data(gbk_tx_pkg->D8, (gbk_tx_pkg->prm.len + 4));
	}
}

void config_app_handle(void)
{
	GetCfgViaUartRx();
}
