#include "HW_Config.h"
#include "uart_linkage_drv.h"
#include "CnCpp.h"

#define LINKAGE_UART 	3

typedef union{
	unsigned int D32;
	unsigned char D8[4];
	struct{
		unsigned char Cmd;
		unsigned char Order;
		unsigned char CarryByte;
		unsigned char PriRoutingIdf;
	}Id;
}TC2CIdBody;

static unsigned int uart_tx_error_flag = 0;

unsigned int get_uart_tx_error_flag(void)
{
	return uart_tx_error_flag;
}

void uart3_rx_task(void)
{
	unsigned int Cmd;
	
	if(uart_info_8bit[LINKAGE_UART].rx_complete){
		uart_info_8bit[LINKAGE_UART].rx_complete = 0;
		if((uart_info_8bit[LINKAGE_UART].rx_len <= 13)&&(uart_info_8bit[LINKAGE_UART].rx_len >= 5)){
			if((uart_info_8bit[LINKAGE_UART].rx_len - 5) == uart_info_8bit[LINKAGE_UART].rx_buf[4]){
				Cmd = uart_info_8bit[LINKAGE_UART].rx_buf[3];
				Cmd<<=8;
				Cmd |= uart_info_8bit[LINKAGE_UART].rx_buf[2];
				Cmd<<=8;
				Cmd |= uart_info_8bit[LINKAGE_UART].rx_buf[1];
				Cmd<<=8;
				Cmd |= uart_info_8bit[LINKAGE_UART].rx_buf[0];
				LoadOuterCanRxMsg(Cmd, (&uart_info_8bit[LINKAGE_UART].rx_buf[5]), uart_info_8bit[LINKAGE_UART].rx_buf[4]);
			}else
			if(5 == uart_info_8bit[LINKAGE_UART].rx_len){
				if(14 == uart_info_8bit[LINKAGE_UART].rx_buf[4]){//ALL_FULL_FLAG
					uart_tx_error_flag = 3;
				}else
				if(12 == uart_info_8bit[LINKAGE_UART].rx_buf[4]){//CLOSE_FULL_FLAG
					uart_tx_error_flag = 2;
				}else
				if(16 == uart_info_8bit[LINKAGE_UART].rx_buf[4]){//ERR_HANDLE_FLAG   can send fail
					uart_tx_error_flag = 1;
				}else
				if(20 == uart_info_8bit[LINKAGE_UART].rx_buf[4]){//recover from error
					uart_tx_error_flag = 0;
				}
				SetOuterCanTxMsgState(uart_tx_error_flag);
			}
		}else{
			if((0x5A == uart_info_8bit[LINKAGE_UART].rx_buf[uart_info_8bit[LINKAGE_UART].rx_len-1]) && \
				 (0xA5 == uart_info_8bit[LINKAGE_UART].rx_buf[0]) && \
				((uart_info_8bit[LINKAGE_UART].rx_buf[2] + 4) == uart_info_8bit[LINKAGE_UART].rx_len)){
				GetHwInfo(uart_info_8bit[LINKAGE_UART].rx_buf[3],1,&uart_info_8bit[LINKAGE_UART].rx_buf[3]);
				GetHwInfo(uart_info_8bit[LINKAGE_UART].rx_buf[11],0,&uart_info_8bit[LINKAGE_UART].rx_buf[11]);
			}
		}
	}
}

void uart_linkage_task(void)
{
	uart3_rx_task();
}

unsigned int get_excan_linkage_tx_complete(void)
{
	return get_uart_tx_complete_delay_flag(LINKAGE_UART);
}

void uart_linkage_tx_data(unsigned char * pdata, unsigned int len)
{
	uart_tx_over(LINKAGE_UART, pdata, len);
}

unsigned int outer_can_send_data(volatile unsigned int head, volatile unsigned char * pdata, volatile unsigned int len)
{
	unsigned int i = 0;
	
	static TC2CIdBody exId;
	
	if(len > 8)return 1;
	if(!get_excan_linkage_tx_complete())return 1;
	
	exId.D32 = head;
	
	USART3->TDR = exId.Id.Cmd;
	USART3->TDR = exId.Id.Order;
	USART3->TDR = exId.Id.CarryByte;
	USART3->TDR = exId.Id.PriRoutingIdf & 0b00011111;
	USART3->TDR = len;
	for(i=0;i<len;i++){
		USART3->TDR = pdata[i];
	}
	uart_info_8bit[LINKAGE_UART].tx_complete = 1;
	uart_info_8bit[LINKAGE_UART].tx_complete_delay_flag = 0;
	uart_info_8bit[LINKAGE_UART].tx_complete_delay_tick= 0;
	return 0;
}

void get_commbrd_ver_modle(void)
{
	while(0 == get_excan_linkage_tx_complete());
	USART3->TDR = 0xA5;
	USART3->TDR = 0x50;
	USART3->TDR = 0;
	USART3->TDR = 0x5A;
	uart_info_8bit[LINKAGE_UART].tx_complete = 1;
	uart_info_8bit[LINKAGE_UART].tx_complete_delay_flag = 0;
	uart_info_8bit[LINKAGE_UART].tx_complete_delay_tick= 0;
}

unsigned int outer_can_send_data_(unsigned int head, unsigned char * pdata, unsigned int len)
{
	unsigned int i = 0;
	unsigned char data[16] = {0};
	
	TC2CIdBody exId;
	
	if(len > 8)return 1;
	if(!get_excan_linkage_tx_complete())return 1;
	
	exId.D32 = head;
	
	data[0] = exId.Id.Cmd;
	data[1] = 0;
	data[2] = 0;
	data[3] = (exId.Id.PriRoutingIdf) & (0b00011111); 
	data[4] = len;
	for(i=0;i<len;i++){
		data[5+i] = pdata[i];
	}
	
	uart_linkage_tx_data(data, (len+5));
	
	return 0;
}
