#include "simulator_uart_app.h"
#include "simulator_uart_driver.h"
#include "main.h"

extern uint8_t dma_tx_success_flag;
extern uint8_t dma_rx_success_flag;
extern uint32_t srcBuffer[12];
extern uint32_t dstBuffer[12];
uint8_t rxData = 0;

/*
   lsb: 0  lsb
        1  msb
 */
void simulator_uart_tx(SIMU_UART_CONFIG_T *uartConfig, uint8_t txData)
{
	uint8_t i=0;
	uint8_t highLevelCnt = 0;
	
	if (uartConfig->mlsb)
	{
		/* msb */
		srcBuffer[0] = GPIO_PIN_0;
		for (i=8;i>0;i--)
		{
			if ((txData >> i)&0x01)
			{
				srcBuffer[i] = (uint32_t)GPIO_PIN_0 << 16U;
				highLevelCnt++;
			}
			else
			{
				srcBuffer[i] = GPIO_PIN_0;
			}
		}
		
		if (uartConfig->parity == UART_PARITY_NONE)
		{
			srcBuffer[9] = (uint32_t)GPIO_PIN_0 << 16U;
			srcBuffer[10] = (uint32_t)GPIO_PIN_0 << 16U;
			dma_trans_tx(11);
		}
		else if(uartConfig->parity == UART_PARITY_ODD) 
		{
			if (highLevelCnt%2)
			{
				srcBuffer[9] = GPIO_PIN_0;
			}
			else
			{
				srcBuffer[9] = (uint32_t)GPIO_PIN_0 << 16U;
			}
			
			srcBuffer[10] = (uint32_t)GPIO_PIN_0 << 16U;
			srcBuffer[11] = (uint32_t)GPIO_PIN_0 << 16U;
			dma_trans_tx(12);
		}
		else if (uartConfig->parity == UART_PARITY_EVEN)
		{
			if (highLevelCnt%2)
			{
				srcBuffer[9] = (uint32_t)GPIO_PIN_0 << 16U;
			}
			else
			{
				srcBuffer[9] = GPIO_PIN_0;
			}
			
			srcBuffer[10] = (uint32_t)GPIO_PIN_0 << 16U;
			srcBuffer[11] = (uint32_t)GPIO_PIN_0 << 16U;
			dma_trans_tx(12);
		}
	}
	else
	{
		/* lsb */
		srcBuffer[0] = GPIO_PIN_0;
		for (i=0;i<8;i++)
		{
			if ((txData >> i)&0x01)
			{
				srcBuffer[i+1] = (uint32_t)GPIO_PIN_0 << 16U;
				highLevelCnt++;
			}
			else
			{
				srcBuffer[i+1] = GPIO_PIN_0;
			}
		}
		if (uartConfig->parity == UART_PARITY_NONE)
		{
			srcBuffer[9] = (uint32_t)GPIO_PIN_0 << 16U;
			srcBuffer[10] = (uint32_t)GPIO_PIN_0 << 16U;
			dma_trans_tx(11);
		}
		else if(uartConfig->parity == UART_PARITY_ODD) 
		{
			if (highLevelCnt%2)
			{
				srcBuffer[9] = GPIO_PIN_0;
			}
			else
			{
				srcBuffer[9] = (uint32_t)GPIO_PIN_0 << 16U;
			}
			
			srcBuffer[10] = (uint32_t)GPIO_PIN_0 << 16U;
			srcBuffer[11] = (uint32_t)GPIO_PIN_0 << 16U;
			dma_trans_tx(12);
		}
		else if (uartConfig->parity == UART_PARITY_EVEN)
		{
			if (highLevelCnt%2)
			{
				srcBuffer[9] = (uint32_t)GPIO_PIN_0 << 16U;
			}
			else
			{
				srcBuffer[9] = GPIO_PIN_0;
			}
			
			srcBuffer[10] = (uint32_t)GPIO_PIN_0 << 16U;
			srcBuffer[11] = (uint32_t)GPIO_PIN_0 << 16U;
			dma_trans_tx(12);
		}
	}
}

SIMU_UART_CONFIG_T uart_config;
void uart_init(void)
{
	uart_config.mlsb = 0;
	uart_config.parity = UART_PARITY_NONE;
	/* BUAD9600: T = 104.16us*/
	uart_config.txBaud = 0x19;   /*(txBaud+1)/8M *16 = 104.16us, txBaud =  51*/
	uart_config.rxBaud = 0x1457;  /*(txBaud+1)/100M = 104.16us, txBaud =  10415*/
	if(uart_config.parity == UART_PARITY_NONE)
	{
		dma_trans_rx(10); /* start next cycle dma receive,wait ebus trigger */
	}			
	else
	{
		dma_trans_rx(11); /* start next cycle dma receive,wait ebus trigger */
	}
}
void uart_data_send(uint8_t *pData,uint16_t dataLen)
{
	uint16_t i=1;
	dma_tx_success_flag = 0;
	BTIM00->LD   = uart_config.txBaud;
	SET_BIT(BTIM00->CTRL, 0x1);
	simulator_uart_tx(&uart_config,pData[0]);
	while(i<dataLen)
	{
		if(dma_tx_success_flag == 1)
		{
			dma_tx_success_flag = 0;
			BTIM00->LD   = uart_config.txBaud;
			SET_BIT(BTIM00->CTRL, 0x1);
			simulator_uart_tx(&uart_config,pData[i]);
			i++;
		}
	}
}


uint8_t simulator_uart_rx(void)
{
	uint8_t i=0,porityNum =0;
	
	rxData = 0;
	for (i=1;i<=8;i++)
	{
		rxData	|= ((dstBuffer[i]&UART_PIN_RX)>>1) <<(i-1);
		if (((dstBuffer[i]&UART_PIN_RX)>>1) && 0x01)
		{
			porityNum++;
		}
	}
	
	if(uart_config.parity == UART_PARITY_ODD)
	{
		if (porityNum%2)  /* single */
		{
			if (dstBuffer[9] == 1)
			{
				return UART_RECE_PARITY_ERR;
			}
		}
		else              /* double */
		{
			if (dstBuffer[9] == 0)
			{
				return UART_RECE_PARITY_ERR;
			}
		}
	}
	else if (uart_config.parity == UART_PARITY_EVEN)
	{
		if (porityNum%2)  /* single */
		{
			if (dstBuffer[9] == 0)
			{
				return UART_RECE_PARITY_ERR;
			}
		}
		else              /* double */
		{
			if (dstBuffer[9] == 1)
			{
				return UART_RECE_PARITY_ERR;
			}
		}
	}
	
	
	if(uart_config.parity == UART_PARITY_NONE)
	{
		dma_trans_rx(10); /* start next cycle dma receive,wait ebus trigger */
	}			
	else
	{
		dma_trans_rx(11); /* start next cycle dma receive,wait ebus trigger */
	}
		
	
	return UART_RECE_OK;
}

uint8_t uart_data_receive(uint8_t *pData, uint16_t dataLen)
{
	uint8_t result=0;
	uint16_t i=0;
	uint32_t tickStart = 0U;
	
	memset(pData,0,dataLen);
	tickStart = DDL_GetTick();
	while(i<dataLen)
	{
		if (dma_rx_success_flag)
		{
			dma_rx_success_flag = 0;
			/* process receive data */
			result = simulator_uart_rx();
			if (result != UART_RECE_OK)
			{
				memset(pData,0,dataLen);
				return result;
			}
			pData[i++] = rxData;	
			
			tickStart = DDL_GetTick();
		}
		if ((DDL_GetTick() - tickStart ) > 1000)
		{
			return UART_RECE_TIMEOUT;/*timeout*/
		}
	}
	return result;
}





