#include "modbus.h"

MODH_T g_tModH;

extern uint8_t FLAG_FrameData;
extern UART_HANDLE hUART0;
volatile uint8_t flag = 0;
uint8_t count = 0;              //ռ
uint8_t CocheData[64];      //ʱݻ

uint16_t  Time = 0;

uint32_t Flash_Address;

uint8_t Time_1[] = "ʱ5!!!\n";
uint8_t Time_2[] = "ʱ4!!!\n";
uint8_t Time_3[] = "ʱ3!!!\n";
uint8_t Time_4[] = "ʱ2!!!\n";
uint8_t Time_5[] = "ʱ1!!!\n";
uint8_t Time_6[] = "ڽû!!!\n";

int Hardware1_StartAddress, Hardware1_EndAddress, Hardware_StartSector;
int Hardware2_StartAddress, Hardware2_EndAddress, Hardware_EndSector;


static void MODH_Read_01H(void);
static void MODH_Read_02H(void);
static void MODH_Read_03H(void);
static void MODH_Read_04H(void);
static void MODH_Read_05H(void);
static void MODH_Read_10H(void);
extern alt_u8 uart0_tx_state;//0״̬
void ModBus_ReceieveCMD(UART_HANDLE hUART0)
{
//	uint8_t i;
//	uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
//	count = UARTx_Rx(hUART0,(alt_u8 *)g_tModH.RxBuf); //Ӵڽյ
//	if (count == 8) {  //ڽյһ֡
//		flag = 1;  //״̬־λ
//		Time = 0;
//		FLAG_FrameData = 0;
//		if(g_tModH.RxBuf[0] == SlaveAddr){ //⴮ڽյĵһλǷΪӻַ
//			MODH_AnalyzeApp(hUART0); //յ
//		}
//		else
//			UARTx_Tx(hUART0,(alt_u8 *)"Slave Address error!\n",sizeof("Slave Address error!\n")-1);
//		}
	uint8_t i;
	if (FLAG_FrameData) {  //ڽյһ֡
		flag = 1;  //״̬־λ
		FLAG_FrameData = 0;
		CopyCocheData(g_tModH.RxBuf,sizeof(g_tModH.RxBuf) - 1); //Ӵڽյ
		if(g_tModH.RxBuf[0] == SlaveAddr){ //⴮ڽյĵһλǷΪӻַ
			MODH_AnalyzeApp(); //յ
		}
		else
			printf("Slave Address error!\n");
		}
	else if(Time == 0 && flag == 0){
		UARTx_Tx(hUART0, Time_1, sizeof(Time_1)-1);
		uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
		usleep(1000000);    //ʱ1S
		Time = Time +1;
	}
	else if(Time == 1 && flag == 0){ //ʱʱ1Sδ״̬
		UARTx_Tx(hUART0, Time_2, sizeof(Time_2)-1);
		uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
		usleep(1000000);    //ʱ1S
		Time = Time +1;
	}
	else if(Time == 2 && flag == 0){ //ʱʱ2Sδ״̬
		UARTx_Tx(hUART0, Time_3, sizeof(Time_3)-1);
		uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
		usleep(1000000);    //ʱ1S
		Time = Time +1;
	}
	else if(Time == 3 && flag == 0){ //ʱʱ3Sδ״̬
		UARTx_Tx(hUART0, Time_4, sizeof(Time_4)-1);
		uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
		usleep(1000000);    //ʱ1S
		Time = Time +1;
	}
	else if(Time == 4 && flag == 0){ //ʱʱ4Sδ״̬
		UARTx_Tx(hUART0, Time_5, sizeof(Time_5)-1);
		uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
		usleep(1000000);    //ʱ1S
		Time = Time +1;
	}
	else if(Time == 5 && flag == 0){ //ʱ5Sûнյκָûڸ״̬ʱĬϽûAPP1
		UARTx_Tx(hUART0, Time_6, sizeof(Time_6)-1);
		uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
		usleep(1000);    //ʱ
		Hardware1_StartAddress		= Hardware1_StA;
//		jump_hardware1();
		Time = 0;
	}
}
//תAPP1ĳ
void jump_hardware1()
{
	IOWR(REMOTE_UPDATE_BASE, 0x0C, 0); //
	//Write start address
	IOWR(REMOTE_UPDATE_BASE, 0x10, Hardware1_StartAddress); //3
	//Trigger reconfiguration
	IOWR(REMOTE_UPDATE_BASE, 0x1D, 1); // 6
}

//תAPP2ĳ
void jump_hardware2()
{
	IOWR(REMOTE_UPDATE_BASE, 0x0C, 0); //
	//Write start address
	IOWR(REMOTE_UPDATE_BASE, 0x10, Hardware2_StartAddress); //3
	//Trigger reconfiguration
	IOWR(REMOTE_UPDATE_BASE, 0x1D, 1); // 6
}
/*
*********************************************************************************************************
*	  : MODH_AnalyzeApp
*	˵: ӦòЭ顣Ӧ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
void MODH_AnalyzeApp(UART_HANDLE hUART0)
{	
	switch (g_tModH.RxBuf[1])			/* 2ֽ  */
	{
		case 0x01:	/* ȡȦ״̬ */
			MODH_Read_01H();
			break;
		case 0x02:	/* ȡ״̬ */
			MODH_Read_02H();
			break;
		case 0x03:	/* ȡּĴ һּĴȡõǰĶֵ */
			MODH_Read_03H();
			break;
		case 0x04:	/* ȡĴ */
			MODH_Read_04H();
			break;
		case 0x05:	/* ǿƵȦ */
			MODH_Read_05H();
			break;
		case 0x06:	/* дĴ */
			MODH_Read_06H(hUART0);
			break;	
		case 0x10:	/* дĴ */
			MODH_Read_10H();
			break;		
		default:
//			printf("Function error!\n");
			UARTx_Tx(hUART0, (alt_u8 *)"Function error!\n",sizeof("Function error!\n"));
			break;
	}
}
/*
*********************************************************************************************************
*	  : MODH_Read_01H
*	˵: 01HָӦ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
static void MODH_Read_01H(void)
{

}

/*
*********************************************************************************************************
*	  : MODH_Read_02H
*	˵: 02HָӦ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
static void MODH_Read_02H(void)
{
	
}

/*
*********************************************************************************************************
*	  : MODH_Read_04H
*	˵: 04HָӦ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
static void MODH_Read_04H(void)
{
	
}

/*
*********************************************************************************************************
*	  : MODH_Read_05H
*	˵: 05HָӦ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
static void MODH_Read_05H(void)
{
	
}

/*
*********************************************************************************************************
*	  : MODH_Read_06H
*	˵: 06HָӦ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
void MODH_Read_06H(UART_HANDLE hUART0)
{
	uint16_t RX_Command;
	uint16_t CRC;
	uint8_t i;
	uint8_t DeviceID = 0;
	uint32_t FlashID = 0;
	uint8_t app_x = 0;
	int writeAddress, tempAddress, receivedHex[4], byte;
    RX_Command = ((uint16_t)g_tModH.RxBuf[4] << 8) | g_tModH.RxBuf[5];  //ԤõĵĴֵ
	CRC = ((uint16_t)g_tModH.RxBuf[6] << 8) | g_tModH.RxBuf[7]; //Уֵ
	if(((g_tModH.RxBuf[2] << 8) |  g_tModH.RxBuf[3]) == REG_Address){  //жϽյļĴַǷȷ
		switch(RX_Command << 8 | CRC)
		{
			case Erase_FlashSector << 8 | Erase_FlashSector_CRC:
			{
				//ж֮սbuffer¿ʼ
				for(i = 0;i < 12;i++){
					g_tModH.RxBuf[i] = 0;
					i++;
				}
				CMD_FlashErase(hUART0,SectorErase);//flash

				break;
			}

			case Get_App2_addr << 8 | Get_App2_addr_CRC:     //ûAPP2ʼַ
			{
				Hardware2_StartAddress = CMD_QAM(hUART0,"APP2ʼַ:\n");
				break;
			}

			case Write_Flash << 8 | Write_Flash_CRC:  //Flashд
			{
				app_x = CMD_QAM(hUART0," ҪµAPP:\n");
				if(app_x == 1)
				{
					Hardware1_StartAddress = Hardware1_StA;
					if(Hardware2_StartAddress <= Hardware1_StartAddress) //˵ûֻҪAPP1ҪAPP2
					{
						Hardware1_EndAddress = Hardware2_End;
					}
					else
					{
						Hardware1_EndAddress = Hardware2_StartAddress - 1000;
					}
//					printf("Enter programming file...\r\n");
					UARTx_Tx(hUART0, (alt_u8 *)"Enter programming file...\r\n",sizeof("Enter programming file...\r\n"));
					for(writeAddress=Hardware1_StartAddress; writeAddress<=Hardware1_EndAddress; writeAddress=writeAddress+4)
					{
						//Get 4 bytes from UART terminal
						//scanf("%2x%2x%2x%2x", &receivedHex[0], &receivedHex[1], &receivedHex[2], &receivedHex[3]);

						for(int i=0;i<4;i++)
//								receivedHex[i]=alt_getchar();
						//Swap LSB with MSB
						for(byte=0; byte<4; byte++)
						{
							receivedHex[byte] = ((receivedHex[byte] & 0xAA) >> 1) | ((receivedHex[byte] & 0x55) << 1);
							receivedHex[byte] = ((receivedHex[byte] & 0xCC) >> 2) | ((receivedHex[byte] & 0x33) << 2);
							receivedHex[byte] = ((receivedHex[byte] & 0xF0) >> 4) | ((receivedHex[byte] & 0x0F) << 4);
						}

						//Write into flash
						tempAddress = writeAddress;
						for(i=0; i<4; i++)
						{
							IOWR_8DIRECT(EPCQ_CONTROLLER_AVL_MEM_BASE, tempAddress, receivedHex[i]);
							tempAddress++;
						}
					}
//					printf("Application Hardware1 upgrade completed!\r\n");
					UARTx_Tx(hUART0, (alt_u8 *)"Application Hardware1 upgrade completed!\r\n",sizeof("Application Hardware1 upgrade completed!\r\n"));
				}
				else if(app_x == 2)    //ҪµAPP2
				{
					if(Hardware2_StartAddress <= Hardware1_StartAddress) //˵û֮ǰûиAPP2ĵַ
					{
//						printf("ȸAPP2ʼַ!!!\n\r");
						UARTx_Tx(hUART0, (alt_u8 *)"ȸAPP2ʼַ!!!\n\r",sizeof("ȸAPP2ʼַ!!!\n\r"));
					}
					else
					{
						Hardware2_EndAddress = Hardware2_End;
//						printf("Enter programming file...\r\n");
						UARTx_Tx(hUART0, (alt_u8 *)"ȸAPP2ʼַ!!!\n\r",sizeof("ȸAPP2ʼַ!!!\n\r"));

						for(writeAddress=Hardware2_StartAddress; writeAddress<=Hardware2_EndAddress; writeAddress=writeAddress+4)
						{
							//Get 4 bytes from UART terminal
							//scanf("%2x%2x%2x%2x", &receivedHex[0], &receivedHex[1], &receivedHex[2], &receivedHex[3]);

							for(int i=0;i<4;i++)
//									receivedHex[i]=alt_getchar();
							//Swap LSB with MSB
							for(byte=0; byte<4; byte++)
							{
								receivedHex[byte] = ((receivedHex[byte] & 0xAA) >> 1) | ((receivedHex[byte] & 0x55) << 1);
								receivedHex[byte] = ((receivedHex[byte] & 0xCC) >> 2) | ((receivedHex[byte] & 0x33) << 2);
								receivedHex[byte] = ((receivedHex[byte] & 0xF0) >> 4) | ((receivedHex[byte] & 0x0F) << 4);
							}

							//Write into flash
							tempAddress = writeAddress;
							for(i=0; i<4; i++)
							{
								IOWR_8DIRECT(EPCQ_CONTROLLER_AVL_MEM_BASE, tempAddress, receivedHex[i]);
								tempAddress++;
							}
						}
//						printf("Application Hardware2 upgrade completed!\r\n");
						UARTx_Tx(hUART0, (alt_u8 *)"Application Hardware2 upgrade completed!\r\n",sizeof("Application Hardware2 upgrade completed!\r\n"));
					}
				}
				break;
			}

			case Start_APP1 << 8 | Start_APP1_CRC:  //״̬תû
			{
				jump_hardware1();
				break;
			}

			case Start_APP2 << 8 | Start_APP2_CRC:  //״̬תû
			{
				jump_hardware2();
				break;
			}

			default:
				//ж֮սbuffer¿ʼ
				for(i = 0;i < 8;i++){
					g_tModH.RxBuf[i] = 0;
					i++;
				}
//				printf("Preset Data or CRC error!\n");
				UARTx_Tx(hUART0, (alt_u8 *)"Preset Data or CRC error!\n",sizeof("Preset Data or CRC error!\n"));
				break;
		}
	}
	else
//		printf("Register address error!\n");
		UARTx_Tx(hUART0, (alt_u8 *)"Register address error!\n",sizeof("Register address error!\n"));
}

/*
*********************************************************************************************************
*	  : MODH_Read_03H
*	˵: 03HָӦ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
void MODH_Read_03H(void)
{
	
}

/*
*********************************************************************************************************
*	  : MODH_Read_10H
*	˵: 10HָӦ
*	    : 
*	  ֵ: 
*********************************************************************************************************
*/
void MODH_Read_10H(void)
{
	
}

void delay(uint32_t t)
{
	t= t*250;
	while(t--);
}
