
#include<at89c5131.h>
#include<stdio.h>
#include<keyscan.h>

#define I2C_IDLE   0x00
#define I2C_BUSY   0x01
#define I2C_BUSYTX 0x03
#define I2C_BUSYRX 0x05
#define I2C_OK     0x02
#define I2C_ERROR  0x04
#define ACK	0x00			  	// ACK Signal
#define NACK 0x01			  	// NACK Signal

sbit bk_lit = P2^2;
sbit latch_en = P3^3;               //active low signal
sbit RS = P3^4;
sbit lcd_en = P3^5;

bit err;
bit b_TWI_busy=0;

unsigned char dt[6];
unsigned char i=0;
unsigned char rw;                       /* 0=write, 1=read */
unsigned char   mi2cstatus,mslaveaddress;
unsigned int mbytenum;

sbit led1 = P2^0;
sbit led2 = P2^1;

/***************************************************************************************************************/
void it_TWI(void) interrupt 8 using 1
{
	switch(SSCS)                     			/* TWI status tasking */
    {
		case(0x00):                			/* A start condition has been sent */
      		                         			/* SLR+R/W are transmitted, ACK bit received*/
			b_TWI_busy=0;  			/* TWI is free */
			break;

		case(0x08):                		     /* A start condition has been sent */
		case(0x10):
			SSDAT = mslaveaddress; 	 /* send slave adress and read/write bit */
			SSCON &= 0x0DF;			 /* clear start condition */
			SSCON &= 0x0EF;
			mbytenum=0;
			break;

		case(0x18):
			/* SLR+W was transmitted, ACK bit received */
			//SSDAT = i2c_master_getbyte(mbytenum);
			//i2c_master_getbyte(mbytenum);	/* Transmit data byte, ACK bit received */
			SSDAT = 0x00;
			SSCON &= 0x0DF;
			SSCON &= 0x0EF;
			break;

      	case(0x20):
			SSCON &= 0x0DF;			/* SLR+W was transmitted, NOT ACK bit received */
      		SSCON |= 0x10;          /* Transmit STOP */
      		b_TWI_busy=0;           /* TWI is free */
      		mi2cstatus = I2C_ERROR;
			break;

      	case(0x28):
			if(mbytenum ==4)
			{
				SSCON &= 0x0EF;
				SSCON |=0x10;
				mi2cstatus = I2C_OK;
				led1=1;
				//b_TWI_busy=0;
				//mbytenum=0;
			}
			else
			{
				mbytenum++;
				SSDAT =i2c_master_getbyte(mbytenum);		//i2c_master_getbyte(mbytenum);

				SSCON &= 0x0DF;
				SSCON &= 0x0EF;
			}
      		break;

			case(0x30):
				SSCON &= 0x0DF;			// DATA was transmitted,NOT ACK bit received
      			SSCON |= 0x10;          //Transmit STOP
      			b_TWI_busy=0;			// TWI is free
				mi2cstatus = I2C_ERROR;
				break;


			case(0x38):                			// Arbitration lost in SLA+W or DATA.
				SSCON |= 0x20;
				SSCON &= 0x0EF;
				b_TWI_busy=0;           // TWI is free
      			//wr_lcd_dw(0x67);
				break;

	}
	SSCON &= 0xF7;                     // clear flag

}

//*************************************************************************************
void main()
{
	led1=led2=0;
	init_lcd();
	init_i2c();
	bk_lit=0;
 	mbytenum=0;
	mslaveaddress=0x0A0;                 			// slave adresse example
	EA=1;                            				// interrupt enable
	while(1)
	{
		if(!b_TWI_busy && ((SSCON&0x10)!=0x10))		// if the TWI is free
		{
			b_TWI_busy=1;							// flag busy =1
			rw=0;									// 0=write
			SSDAT = 0x00;							// clear buffer before sending data
			SSCON |= 0x20;							// TWI start sending
		}
	}
}
/***************************************************************************************************************/
void init_lcd()
{

	wr_lcd_cw(0x30);
	wr_lcd_cw(0x30);
	wr_lcd_cw(0x30);
			                // 0 0 1 DL N F 0 0     DL=1 8 bit inetrface
							//						N = 1  no. of lines 'two'
							//						F = 0  font size 5x7
	wr_lcd_cw(0x38);
							//0 0 0 1 S/C R/L 0 0	S/C = 0  Cursor on
							//						R/L = 1  Shift one space right
	wr_lcd_cw(0x14);
 							//0 0 0 0 1 D C B		D = 1  screen on
							//						C = 1  cursor on
							//				 		B = 1  blink on
	wr_lcd_cw(0x0F);
							//0 0 0 0 0 1 I/O S    	I/O = 1  cursor moves right
							//					 	S =0     shift cursor
	wr_lcd_cw(0x06);
							//0 0 0 0 0 0 1 0     	clear and home cursor
	wr_lcd_cw(0x01);

	delay_ms(50);
}

//--------------------- delay------------------------------------------------
void delay(unsigned char dly)
{
	for(;dly!=0;dly--);
}

void delay_ms(unsigned char dly_ms)
{
	for(;dly_ms!=0;dly_ms--)
		delay(100);
}

//------------------function to write commands to LCD-------------------------
void wr_lcd_cw(unsigned char cmd)
{
 	P0=cmd;
	RS = 0;					//send command
 	toggle_e();
}
//------------------function to enable LCD-------------------------------------
void toggle_e()
{
	latch_en = 0;			//enable latch
	lcd_en = 1;
	delay_ms(50);
	lcd_en = 0;
	latch_en=1;				//disable latch
}
//----------------function to write Data to LCD----------------------------------

void wr_lcd_dw(unsigned char dta)
{
	P0 = dta;
	RS = 1;		  			// send data
	toggle_e();
}
/************************************************************************
DESC:    gets the next byte to be transmitted when operating as
         a master
RETURNS: byte to transmit
************************************************************************/
unsigned char i2c_master_getbyte(unsigned int bytenum)
{

  unsigned char array[5]={0x66,0x67,0x68,0x69,0x6A};
  return (array[bytenum]);
}


//***********************************************************************
void init_i2c()
{
	P4_1 =1;
    P4_0 =1;

	SSCON = 0xC2; 						// enable TWI interrupt

	IPH1 = 0x02;
	IPL1 = 0x02;

	IEN1 = 0x02;

	mi2cstatus = I2C_IDLE;
}

