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



void help()
{
	printf("i2ctool <cmd>\n");
	printf("    --scan [channel]: scan i2c bus\n");
	printf("    --write [channel] -t [target address] -d [data...]: write i2c data.\n");
}

int str2uint8(char* str, uint8_t *value)
{
	uint8_t val = 0;
	char chr;
	if(sizeof(str) > 2)		//maybe hex
	{
		if((strncmp(str, "0x", 2) == 0) || (strncmp(str, "0X", 2) == 0))
		{			
			if(strlen(str) > 4)
			{
				printf("Invalid hex %s\n", str);
				return -1;
			}

			chr = str[2];
			if((chr >= '0') && (chr <= '9'))
			{
				val = chr - '0';
			}
			else if((chr >= 'a') && (chr <= 'f'))
			{
				val = chr - 'a' + 10;
			}
			else if((chr >= 'A') && (chr <= 'F'))
			{
				val = chr - 'A' + 10;
			}
			else
			{
				printf("Invalid hex %s\n", str);
				return -1;
			}

			if(str[3] != '\0')
			{
				chr = str[3];
				val <<= 4; 
				if((chr >= '0') && (chr <= '9'))
					val += chr - '0';
				else if((chr >= 'a') && (chr <= 'f'))
					val += chr - 'a' + 10;
				else if((chr >= 'A') && (chr <= 'F'))
					val += chr - 'A' + 10;
				else
				{
					printf("Invalid hex %s\n", str);
					return -1;
				}
			}
		}
		else	//dec
		{
			val = atoi(str);
		}
	}
	else	//dec
	{
		val = atoi(str);
	}

	*value = val;
	return 0;
}

int main(int argc, char* argv[])
{
	int fd;
	int i;
	int ret;
	uint8_t buf[100];
	uint8_t channel;
	uint8_t target_addr, start_addr = 2, end_addr = 254;
	char devname[20] = {0};
	uint8_t val;


	if(argc < 3)
	{
		help();
		return -1;
	}

	if(strcmp(argv[1], "--scan") == 0)
	{
		//Get Channel
		if(str2uint8(argv[2], &channel) != 0)
		{
			printf("Get Channel failed %s\n", argv[2]);
			return -1;
		}
		sprintf(devname, "/dev/i2c%d", channel);
		printf("\n");
	 	printf("Find Slave I2C device:\n");
		for(i=start_addr;i<=end_addr;i+=2)
		{
			fd = open(devname, O_RDWR);
			ret = stm32_i2c_master_write(fd, i, buf, 0);
			if(ret == 0)
			{
				printf("  %#02x\n", i);
			}
			close(fd);
		}
		printf("\n");

	}
	else if(strcmp(argv[1], "--write") == 0)
	{
		//Get Channel
		if(str2uint8(argv[2], &channel) != 0)
		{
			printf("Get Channel failed %s\n", argv[2]);
			return -1;
		}
		sprintf(devname, "/dev/i2c%d", channel);

		//Get target address
		if((strcmp(argv[3], "-t") == 0) && (argc >= 5))
		{
			if(str2uint8(argv[4], &target_addr) != 0)
			{
				printf("Invalid target address %s\n", argv[4]);
				help();
				return -1;
			}

			if(target_addr & 0x01)
			{
				printf("target_addr must be write!\n");
				return -1;
			}
		}
		else
		{
			printf("Need -t \n");
			help();
			return -1;
		}

		//Get Datas
		if((strcmp(argv[5], "-d") == 0) && (argc >= 7)) 
		{
			for(i=0;i<argc-6;i++)
			{
				if(str2uint8(argv[i+6], &val) != 0)
				{
					printf("Invalid data[%d] = %s\n", i, argv[i+6]);
					return -1;
				}
				buf[i] = val;
			}
		}
		else
		{
			printf("Need -d\n");
			help();
			return -1;
		}
		printf("i2c_%d write %#02x: ", channel, target_addr);
		for(i=0;i<argc-6;i++)
			printf("%02x ", buf[i]);
		printf("\n");
		
		fd = open(devname, O_RDWR);
		ret = stm32_i2c_master_write(fd, target_addr, buf, argc-6);
		if(ret != 0)
		{
			printf("i2ctool write %#02x failed!\n", target_addr);
		}
		close(fd);
	}
	else
	{
		printf("Invalid param %s\n", argv[1]);
		help();
		return -1;
	}

	
	return 0;
}