//
//	redirect to lcd sub-system utility
//		(c) 2019	1YEN Toru
//
//
//	2019/10/26	ver.1.00
//


#define		PROG_NAME	"redir_lcd"
#define		PROG_VERS	"1.00"
#define		PROG_COPY	"(c) 2019 1YEN Toru"


typedef		unsigned	char	uint8;
typedef		unsigned	short	uint16;
typedef		unsigned	int		uint32;


#include	<ctype.h>
#include	<errno.h>
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<unistd.h>
#include	<wiringPi.h>
#include	<wiringPiI2C.h>


const	int		ErrNo=0;				// no error
const	int		ErrBadParam=-1;			// bad parameter
const	int		ErrInit=-2;				// initialization error
const	int		ErrOpen=-3;				// fail to open file
const	int		i2c_slv_adr=0x08;		// i2c: Arduino slave address (default)


int		xtoi (
const	char	*shex)
{
	// convert hexadecimal string to integer
	const	char	*str_c;
	const	char	*hex_c;
	int		ihex;
	const	char	*xdigit="0123456789abcdef";

	ihex=0;
	for (str_c=shex; (*str_c)!='\0'; str_c++)
	{
		hex_c=strchr (xdigit,tolower (*str_c));
		if (hex_c!=NULL)
			ihex=ihex*16 + (hex_c - xdigit);
		else
			break;
	}

	return (ihex);
}


int		main (
int		argc,
char	**argv)
{
	int		idx;
	int		rtncod;
	int		fi2c;
	int		slv_adr;

	// arguments
	slv_adr=i2c_slv_adr;
	for (idx=0; idx<argc; idx++)
	{
		if (idx==0)
			continue;
		else if (strcmp (argv[idx],"-s")==0 && idx + 1<argc)
		{
			// slave address
			idx++;
			slv_adr=xtoi (argv[idx]);
			if (slv_adr<0x08 || 0x78<=slv_adr)
			{
				// ERROR:
				printf ("ERROR: invalid slave address (0x%02x)\n",slv_adr);
				return (ErrBadParam);
			}
		}
		else
		{
			// show help
			printf ("%s ver.%s %s\n",PROG_NAME,PROG_VERS,PROG_COPY);
			printf ("usage: <command> | %s [<options>]\n",PROG_NAME);
			printf ("options:\n");
			printf ("	-h		Show help, this message.\n");
			printf ("	-s <adr>	Slave address <adr>.hex\n");
			printf ("wirings:\n");
			printf ("	3.3V(phys#1) --> L/S.LV\n");
			printf ("	SDA(phys#3) <=> L/S.LV1\n");
			printf ("	SCL(phys#5) <=> L/S.LV2\n");
			printf ("	GND(phys#9) <=> L/S.GND <=> Arduino.GND\n");
			printf ("	Arduino.5V --> L/S.HV\n");
			printf ("	Arduino.SDA <=> L/S.HV1\n");
			printf ("	Arduino.SCL <=> L/S.HV2\n");
			printf ("	Arduino slave address=0x%02x(default)\n",i2c_slv_adr);
			printf ("\n");

			return ((strcmp (argv[idx],"-h")==0)? ErrNo: ErrBadParam);
		}
	}

	// initialize
	rtncod=ErrNo;
	if (wiringPiSetupPhys ()==-1)
	{
		// ERROR:
		rtncod=ErrInit;
		printf ("ERROR: initialize wiringPi library\n");
		perror (NULL);
		return (rtncod);
	}

	// I2C
	fi2c=wiringPiI2CSetup (slv_adr);
	if (fi2c<0)
	{
		// ERROR:
		rtncod=ErrOpen;
		printf ("ERROR: I2C open %d for slave=0x%02x\n",fi2c,i2c_slv_adr);
		perror (NULL);
		return (rtncod);
	}

	// redirection
	int		chr;
	uint8	buf[4];

	chr=fgetc (stdin);
	while (chr!=EOF)
	{
		buf[0]=chr;
		rtncod=write (fi2c,buf,1);
		if (rtncod<0)
			break;
		// continue
		chr=fgetc (stdin);
	}
	if (rtncod<0)
	{
		// ERROR:
		printf ("ERROR: I2C write error\n");
		perror (NULL);
	}
	else
	{
		// success:
		rtncod=ErrNo;
	}

	// close
	close (fi2c);

	return (rtncod);
}

