/*
 * lcmComm_dgus.c
 *
 * Created on : 2020-10-20
 * Update on : 2022-03-01
 * Author : Folus Wen, Eason Yang
 * Version : V0.27
 *
 */

#include 	"lcmComm_dgus.h"

//#define isDebugPrint

//=======================================
// Basic routine
//=======================================
void displayMessageDgus(uint8_t *data, uint16_t len, uint8_t isRX)
{
	uint8_t output[8192];

	memset(output, 0x00, ARRAY_SIZE(output));
	sprintf((char*)output, "%s", (isRX?"RX: ":"TX: "));
	for(uint16_t idx = 0;idx<len;idx++)
	{
		sprintf((char*)output, "%s%02x ", output, data[idx]);
	}

	#ifdef isDebugPrint
	DEBUG_INFO("%s\n", output);
	#endif
}

//=======================================
// Call function (Transmit message into LCD)
//=======================================
int transceiverDgus(int32_t fd, uint8_t *tx, uint16_t tx_len, uint8_t *rx, uint16_t rx_len)
{
	int result = FAIL;
	int len;

	tcflush(fd,TCIOFLUSH);

	#ifdef isDebugPrint
	displayMessageDgus(tx, tx_len, NO);
	#endif

	if(write(fd, tx, tx_len) >= ARRAY_SIZE(tx))
	{
		if(tx[3] == CMD_REG_WRITE_DATA)
		{
			usleep(100);
			len = read(fd, rx, rx_len);
			if(len > 0)
			{
				if((rx[0] == CMD_HEADER_1) && (rx[1] == CMD_HEADER_2))
				{
					if((rx[3] == CMD_REG_WRITE_DATA) && ((rx[4] == CMD_ACK_VALUE_1) && (rx[5] == CMD_ACK_VALUE_2)))
					{
						#ifdef isDebugPrint
						displayMessageDgus(rx, len, YES);
						#endif

						result = PASS;
					}
					else
					{}
				}
				else
				{}
			}
			else
			{}
		}
		else if(tx[3] == CMD_REG_READ_DATA)
		{
			usleep(100);
			len = read(fd, rx, rx_len);
			if(len > 0)
			{
				if((rx[0] == CMD_HEADER_1) && (rx[1] == CMD_HEADER_2))
				{
					if(rx[3] == CMD_REG_READ_DATA)
					{
						#ifdef isDebugPrint
						displayMessageDgus(rx, len, YES);
						#endif

						result = PASS;
					}
					else
					{}
				}
				else
				{}
			}
			else
			{}
		}
		else
		{}
	}
	else
	{}

	return result;
}

//=======================================
// Call function (Write register value function)
//=======================================
int8_t lcdRegisterWrite(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen)
{
	int8_t result = FAIL;
	uint8_t tx[(regType == REG_TYPE_CONTROL? 8 : 6) + dataLen];
	uint8_t rx[128];

	memset(tx, 0x00, sizeof(tx));
	memset(rx, 0x00, sizeof(rx));

	tx[0] = CMD_HEADER_1;
	tx[1] = CMD_HEADER_2;
	tx[2] = (regType == REG_TYPE_CONTROL? 7 : (3 + dataLen));
	tx[3] = CMD_REG_WRITE_DATA;
	tx[4] = (address >> 8) & 0xff;
	tx[5] = (address >> 0) & 0xff;

	if(regType == REG_TYPE_CONTROL)
	{
		if(address == REG_ADDRESS_SET_PAGE_ID)
		{
			tx[6] = 0x5A;
			tx[7] = 0x01;

			memcpy(&tx[8], data, dataLen);
		}
	}
	else
	{
		memcpy(&tx[6], data, dataLen);
	}

	if(fd > 0)
	{
		if(transceiverDgus(fd, tx, ARRAY_SIZE(tx), rx, ARRAY_SIZE(rx)) == PASS)
		{
			result = PASS;
		}
		else
		{}
	}
	else
	{}

	return result;
}

//=======================================
// Call function (Read register value function)
//=======================================
int8_t lcdRegisterRead(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen)
{
	int8_t result = FAIL;
	uint8_t tx[(regType == REG_TYPE_CONTROL? 7 : 8)];
	uint8_t rx[(regType == REG_TYPE_CONTROL? (7 + dataLen) : (8 + dataLen*2))];

	memset(tx, 0x00, sizeof(tx));
	memset(rx, 0x00, sizeof(rx));

	tx[0] = CMD_HEADER_1;
	tx[1] = CMD_HEADER_2;
	tx[2] = (regType == REG_TYPE_CONTROL? 4 : 5);
	tx[3] = CMD_REG_READ_DATA;
	tx[4] = (address >> 8) & 0xff;
	tx[5] = (address >> 0) & 0xff;

	if(regType == REG_TYPE_CONTROL)
	{
		tx[6] = dataLen;
	}
	else if (regType == REG_TYPE_SPECIAL_CONTROL)
	{
		tx[6] = (dataLen >> 8) & 0xff;
		tx[7] = (dataLen >> 0) & 0xff;
	}
	else
	{}

	if(fd > 0)
	{
		if(transceiverDgus(fd, tx, ARRAY_SIZE(tx), rx, ARRAY_SIZE(rx)))
		{
			if(regType == REG_TYPE_CONTROL)
			{
				if((rx[3] == CMD_REG_READ_DATA) && (((rx[4] << 8) | rx[5]) == address))
				{
					memcpy(data, rx + 7, dataLen);
					result = PASS;
				}
				else
				{}
			}
			else if(regType == REG_TYPE_SPECIAL_CONTROL)
			{
				if((rx[3] == CMD_REG_READ_DATA) && (((rx[4] << 8) | rx[5]) == address))
				{
					memcpy(data, rx + 8, dataLen*2);
					result = PASS;
				}
				else
				{}
			}
			else
			{}
		}
		else
		{}
	}
	else
	{}

	return result;
}