/*
 * I2C LCD Example
 * Display date and time on a 16x2 LCD display 
 * and temp (TC74)
 * with I2C interface.
 *
 * LCD.C + I2C.AS + DELAY.AS Written by Marco Maccaferri
 * Update retro, Date 05/10/21
 * Sensor TC74 (Steve Cousins)
 * Compile with HITECH-C
 * C309-8 -O LCDTC74.C I2C.AS DELAY.AS
 */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "i2c.h"

#define LCD_ADDR (0x27 << 1) /* HI-TECH C */
#define TC74_ADDR (0x9A)     /* Sensor SC406 TC74A0 or 0x4D*/
void delay(int ms);
void delay100us(int cnt);

#define PCF_RS 0x01
#define PCF_RW 0x02
#define PCF_EN 0x04
#define PCF_BACKLIGHT 0x08

int _backlight;
int _entrymode;
int _displaycontrol;
int _cols;
int _lines;
int _row_offset[4];

char BCDToDecimal (char bcdByte);
char DecimalToBCD (char decimalByte);

void begin(int cols, int lines);
void clear();
void home();
void setcursor(int col, int row);
void display(int on);
void write(char * s);
void send(int value, int data);
void sendnibble(int halfbyte, int data);
void write2wire(int halfbyte, int isdata, int enable);

void Taste() {
/*        printf("Weiter Enter "); */
        while (getchar() != '\n');         /* wait Enter */
        }

    /* Main program */

int main(int c, char**av) {

        char temp[21];
        char status=0;
        unsigned char bcd;
        unsigned char celsius;

        time_t now;
        struct tm * ltm;

	_backlight = 1;
	_entrymode = 0x02;
	_displaycontrol = 0x04;

        /* printf ("\033[2J\033[H"); */
        /* cls ?? no function  */

    /* read tc74 Temperatur */
        i2c_start();
        i2c_write(0);
        delay100us(16);

        status = i2c_write(TC74_ADDR);    /* 0x9a */
        if(status  == 0)
        {
         begin(16, 2);     
         setcursor(0, 0);
         sprintf(temp, "error i2c = %04d", TC74_ADDR); 
         write(temp);
         setcursor(0, 1);
         sprintf(temp, "   next ENTER   ");
         write(temp);
         i2c_stop();     
         Taste();
         return 0;                /* break */
        }
        else
        {
        i2c_stop();
        i2c_start();
        i2c_write(TC74_ADDR+1);         /* 0x9a + 1 */

        /* celsius = BCDToDecimal(i2c_read(0x00)); */  /* = hex ? */
        bcd        = DecimalToBCD(i2c_read(0x00));
        celsius    = BCDToDecimal(bcd);
        i2c_stop();
}
    /* lcd handling*/ 
        begin(16, 2); 
	
	setcursor(0,0);

        now = time(NULL);
        ltm = localtime(&now);  

    /* date and time */
        sprintf(temp, "%2d/%02d/%04d", ltm->tm_mday, ltm->tm_mon + 1, ltm->tm_year + 1900);
        setcursor(0, 0);
        write(temp);
        sprintf(temp, "%2d:%02d", ltm->tm_hour, ltm->tm_min);
        setcursor(11, 0);
        write(temp);
    /* temperatur = celsius */
        setcursor(0, 1);
        write(" Temp = "); 
        sprintf(temp, "%d C", celsius);     /* write display */
        setcursor(11,1);
        write(temp);

    /* wait enter */
       /* while (getchar() != '\n'); */

        return 0;
}

void begin(int cols, int lines)
{
	int functionflags = 0;
	
	_cols = cols;
	_lines = lines;

	_row_offset[0] = 0x00;
	_row_offset[1] = 0x40;
	_row_offset[2] = 0x00 + cols;
	_row_offset[3] = 0x40 + cols;
	
	if (lines > 1)
		functionflags |= 0x08;
	
	write2wire(0x00, 0, 0);
	delay(50);
	
	_displaycontrol = 0x04;
	_entrymode = 0x02;
	
        sendnibble(0x03, 0);
	delay100us(45);
	sendnibble(0x03, 0);
	delay100us(2);
	sendnibble(0x03, 0);
	delay100us(2);
	sendnibble(0x02, 0);
	
	send(0x20 | functionflags, 0);
	
	clear();
	home();
	display(1);
}

void clear()
{
	send(0x01, 0);
	delay100us(16);
}

void home()
{
	send(0x02, 0);
	delay100us(16);
}

void setcursor(int col, int row)
{
	if (col >= 0 && col < _cols && row >= 0 && row < _lines) {
		send(0x80 | (_row_offset[row] + col), 0);
	}
}

void display(int on)
{
	if (on) {
		_displaycontrol |= 0x04;
	}
	else {
		_displaycontrol &= ~0x04;
	}
	send(0x08 | _displaycontrol, 0);
}

void write(char * s)
{
	while(*s) {
		send(*s++, 1);
	}
}

void send(int value, int data)
{
	sendnibble((value >> 4 & 0x0F), data);
	sendnibble(value & 0x0F, data);
}

void sendnibble(int halfbyte, int data)
{
	write2wire(halfbyte, data, 1);
	delay100us(1);
	write2wire(halfbyte, data, 0);
	delay100us(1);
}

void write2wire(int halfbyte, int isdata, int enable)
{
	int i2cdata = halfbyte << 4;
	if (isdata) {
		i2cdata |= PCF_RS;
	}
	if (enable) {
		i2cdata |= PCF_EN;
	}
	if (_backlight > 0) {
		i2cdata |= PCF_BACKLIGHT;
	}

	i2c_start();
	i2c_write(LCD_ADDR);
	i2c_write(i2cdata);
	i2c_stop();
}
char BCDToDecimal (char bcdByte)
{
 return (((bcdByte & 0xf0) >> 4) * 10) + (bcdByte & 0x0f);
}

char DecimalToBCD (char decimalByte)
{
 return (((decimalByte / 10) << 4) | (decimalByte % 10));
}



