#include <stdio.h>
#include <stdint.h>
#include "driver.h"
#include "hal_interface_api.h"
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

/*
i2c-scan -b 0
*/

int main(int argc, char* argv[])
{
	int fd;
	int i;
	int ret;
	int channel;
	uint8_t target_addr, start_addr = 2, end_addr = 254;
	int regVal, regAddr;
	i2c_arg_t i2c_arg;
	char devname[20] = "/dev/i2c1";
	char chr;
	
	if((argc != 1) && (argc != 3))
	{
		printf("ncp81111_cfg [regAddr] [regVal]\n");
		printf("    regAddr: decimal or hexadecimal start with '0x'\n");
		printf("    regVal: decimal or hexadecimal start with '0x'\n\n");
		printf("example:\n");
		printf("    ncp81111_cfg 51 32\n");
		printf("  = ncp81111_cfg 0x33 32 \n");
		printf("  = ncp81111_cfg 51 0x20\n");
		printf("  = ncp81111_cfg 0x33 0x20\n");
	}

	fd = open(devname, O_RDWR);
	i2c_arg.DevAddress = 0x50;

	if(argc == 3)
	{
		//Get RegAddr
		if((strncmp(argv[1], "0x", 2) == 0) || (strncmp(argv[1], "0X", 2) == 0))
		{			
			if(strlen(argv[1]) > 4)
			{
				printf("Invalid Register Address %s\n", argv[1]);
				close(fd);
				return -1;
			}

			chr = argv[1][2];
			printf("chr2 = %c\n", chr);
			if((chr >= '0') && (chr <= '9'))
			{
				regAddr = chr - '0';
			}
			else if((chr >= 'a') && (chr <= 'f'))
			{
				regAddr = chr - 'a' + 10;
			}
			else if((chr >= 'A') && (chr <= 'F'))
			{
				regAddr = chr - 'A' + 10;
			}
			else
			{
				printf("Invalid Register Address %s\n", argv[1]);
				close(fd);
				return -1;
			}

			if(argv[1][3] != '\0')
			{
				chr = argv[1][3];
				printf("chr3 = %c\n", chr);
				regAddr <<= 4; 
				if((chr >= '0') && (chr <= '9'))
					regAddr += chr - '0';
				else if((chr >= 'a') && (chr <= 'f'))
					regAddr += chr - 'a' + 10;
				else if((chr >= 'A') && (chr <= 'F'))
					regAddr += chr - 'A' + 10;
				else
				{
					printf("Invalid Register Address %s\n", argv[1]);
					close(fd);
					return -1;
				}
			}
		}
		else
		{
			regAddr = atoi(argv[1]);
		}
		//printf("---> RegAddr %#02x(%d) \n", regAddr, regAddr);

		//Get RegVal
		if((strncmp(argv[2], "0x", 2) == 0) || (strncmp(argv[2], "0X", 2) == 0))
		{			
			if(strlen(argv[2]) > 4)
			{
				printf("Invalid Register Address %s\n", argv[2]);
				close(fd);
				return -1;
			}

			chr = argv[2][2];
			if((chr >= '0') && (chr <= '9'))
				regVal = chr - '0';
			else if((chr >= 'a') && (chr <= 'f'))
				regVal = chr - 'a' + 10;
			else if((chr >= 'A') && (chr <= 'F'))
				regVal = chr - 'A' + 10;
			else
			{
				printf("Invalid Register Address %s\n", argv[2]);
				close(fd);
				return -1;
			}

			if(argv[2][3] != '\0')
			{
				chr = argv[2][3];
				regVal <<= 4; 
				if((chr >= '0') && (chr <= '9'))
					regVal += chr - '0';
				else if((chr >= 'a') && (chr <= 'f'))
					regVal += chr - 'a' + 10;
				else if((chr >= 'A') && (chr <= 'F'))
					regVal += chr - 'A' + 10;
				else
				{
					printf("Invalid Register Address %s\n", argv[2]);
					close(fd);
					return -1;
				}
			}			
		}
		else
		{
			regVal = atoi(argv[2]);
		}

		//printf("---> RegVal %#02x(%d)\n", regVal, regVal);

		printf("write reg %#02x(%d), val %#02x(%d)\n", regAddr, regAddr, regVal, regVal);

		//Disable NCP81111
		i2c_arg.Buf[0] = 0x05; //Enter disable state
		i2c_arg.Buf[1] = 0x00;
		i2c_arg.WriteLen = 2;
		ret = ioctl(fd, I2C_MASTER_TRANSFER, &i2c_arg);
		if(ret == -1)
		{
			printf("---> Enter disable error\n");
			close(fd);
			return -1;
		}

		//Configurate user register
		i2c_arg.Buf[0] = 0x02; //write
		i2c_arg.Buf[1] = regAddr;
		i2c_arg.Buf[2] = regVal;
		i2c_arg.WriteLen = 3;
		ret = ioctl(fd, I2C_MASTER_TRANSFER, &i2c_arg);
		if(ret == -1)
		{
			printf("---> write error\n");
			close(fd);
			return -1;
		}

		//Save to NVM
		i2c_arg.Buf[0] = 0x04; //write NVM
		i2c_arg.WriteLen = 1;
		ret = ioctl(fd, I2C_MASTER_TRANSFER, &i2c_arg);
		if(ret == -1)
		{
			printf("---> write NVM error\n");
			close(fd);
			return -1;
		}

		//Enable NCP81111
		i2c_arg.Buf[0] = 0x05; //Enter operation state
		i2c_arg.Buf[1] = 0x09;
		i2c_arg.WriteLen = 2;
		ret = ioctl(fd, I2C_MASTER_TRANSFER, &i2c_arg);
		if(ret == -1)
		{
			printf("---> Enter operation error\n");
			close(fd);
		}
		sleep(1);
	}

	i2c_arg.Buf[0] = 0x01; //read
	i2c_arg.Buf[1] = 0x00;	//register address
	i2c_arg.WriteLen = 2;
	i2c_arg.ReadLen = 110;
	ret = ioctl(fd, I2C_MASTER_TRANSFER_RECEIVE, &i2c_arg);
	if(ret == -1)
	{
		printf("---> read error!\n");
		close(fd);
		return -1;
	}
	else
	{
		printf("======= NCP81111 User Register Map ======= ");
		for(i=0;i<i2c_arg.ReadLen;i++)
		{
			if(i%16 == 0) printf("\n%03d: ", i);
			printf("%02x ", i2c_arg.Buf[i]);
		}
	}

	i2c_arg.Buf[0] = 0x01; //read
	i2c_arg.Buf[1] = 110;	//register address
	i2c_arg.WriteLen = 2;
	i2c_arg.ReadLen = 110;
	ret = ioctl(fd, I2C_MASTER_TRANSFER_RECEIVE, &i2c_arg);
	if(ret == -1)
	{
		printf("---> read error!\n");
		close(fd);
		return -1;
	}
	else
	{
		for(i=0;i<i2c_arg.ReadLen;i++)
		{
			if((i+110)%16 == 0) printf("\n%03d: ", i+110);
			printf("%02x ", i2c_arg.Buf[i]);
		}
		printf("\n");
	}

	close(fd);
	return 0;
}