

#asm
_CP_ON                       EQU     H'000F'
_CP_OFF                      EQU     H'3FFF'
_PWRTE_ON                    EQU     H'3FF7'
_PWRTE_OFF                   EQU     H'3FFF'
_WDT_ON                      EQU     H'3FFF'
_WDT_OFF                     EQU     H'3FFB'
_LP_OSC                      EQU     H'3FFC'
_XT_OSC                      EQU     H'3FFD'
_HS_OSC                      EQU     H'3FFE'
_RC_OSC                      EQU     H'3FFF'
#endasm

//#pragma chip PIC16F84
#pragma config  = _HS_OSC & _WDT_ON & _PWRTE_ON & _CP_OFF

#include "int16CXX.h" //gestion des interuption

#define SCL  RA4
#define SDA  RA3
#define bitSCL 4
#define bitSDA 3

bit  I2C_LAST_SDA;
bit  I2C_LAST_SCL;
bit  I2C_NEW_SDA;
bit  I2C_NEW_SCL;

bit  I2C_BIT_ON;
bit  I2C_BIT_ADR;
bit  I2C_BIT_RD;
bit  I2C_BIT_WR;
bit  I2C_BIT_ACK;

char I2C_CLK;
char I2C_ADR;
char I2C_DAT;
char I2C_NBYTE;
char I2C_TIME;

uns16 t_on;
uns16 t_off;
uns16 t;
bit	  on;

void I2C_Slave_Check();

#pragma origin 0x04
interrupt timer(void)
{
	int_save_registers
	if(T0IF){
		I2C_Slave_Check();

		t++;
		if(on==1 && t >= t_on){
			RB0  = 1;			
			RB1  = 0;
			RB2  = 0;			
			RB3  = 0;
			RB4  = 0;			
			RB5  = 0;
			RB6  = 0;
			RB7  = 0;
						
			t  = 0;
			on = 0;
		}
		if(on==0 && t >= t_off){
			RB0  = 0;			
			RB1  = 1;
			RB2  = 1;			
			RB3  = 1;
			RB4  = 1;			
			RB5  = 1;
			RB6  = 1;
			RB7  = 1;
						
			t  = 0;
			on = 1;
		}
		T0IF = 0;

	}
	int_restore_registers

	clrwdt();
}

//#include "eeprom.c"
//#include "I2C.C"
//#include "I2C_Slave.C"
//#include "I2C_PCF8574.C"





void main(void)
{	
	INTCON = 0b10100000;
	OPTION = 0b11000000;		//Prediviseur : Warchdog every 2.304s

	TRISA = 0b11111111;
	TRISB = 0b00000000;

	RB0 = 1;
	RB1 = 0;
	RB2 = 0;
	RB3 = 0;
	RB4 = 0;
	RB5 = 0;
	RB6 = 0;
	RB7 = 0;

	TMR0  = 0;	

	t_on  = 1000;
	t_off = 2500;
	on	  = 1;

	clrwdt();

	uns16 k = 0;	
	while(k<5){

		uns16 l = 0;
		while(l<10000){
			nop();
			l = l+1;
			clrwdt();
		}

		RB4 = 1;

		l = 0;
		while(l<10000){
			nop();
			l = l+1;
			clrwdt();
		}

		RB4 = 0;

		k = k+1;
	}




	while(1){		
		clrwdt();		
	}

}





// clk :   0 | 1 |					--> CLK=9 = CLK=0 of next byte
// SCL : --__--__
// SDA : --X __X --

void I2C_Slave_Init()
{
	TRISA.bitSCL = 1;		// Lecture
	TRISA.bitSDA = 1;		// Lecture

	I2C_NEW_SCL  = SCL;
	I2C_NEW_SDA  = SDA;	

	I2C_TIME	 = 0;

	clrwdt();
}

bit I2C_Slave_PIC_Adress()
{	
	if(I2C_ADR == 50 || I2C_ADR == 51 || I2C_ADR == 52 || I2C_ADR == 53)	return 1;	
	return 0;			
}


void I2C_Slave_Action()
{	
	I2C_NBYTE++;

	I2C_BIT_RD 	 = 0;
	I2C_BIT_WR 	 = 0;	
	TRISA.bitSDA = 1;
	
	switch(I2C_ADR){
		case 50 :
			I2C_BIT_RD 	= 1;							
			if(I2C_NBYTE>1){				
				t_on 		= I2C_DAT;
				t_on	    = t_on*100;	
				I2C_ADR     = 0;
			}
			break;
		case 51 :
			I2C_BIT_WR 	 = 1;	
			uns16 tmp1	 = t_on/100;
			I2C_DAT		 = (char)tmp1;
			I2C_ADR 	 = 0;
			break;
		case 52 :
			I2C_BIT_RD 	= 1;							
			if(I2C_NBYTE>1){				
				t_off 		= I2C_DAT;
				t_off	    = t_off*100;	
				I2C_ADR     = 0;
			}
			break;
		case 53 :
			I2C_BIT_WR 	 = 1;	
			uns16 tmp2	 = t_off/100;
			I2C_DAT		 = (char)tmp2;
			I2C_ADR 	 = 0;
			break;
	}	
	
	clrwdt();
}


void I2C_Slave_Check()
{
	I2C_LAST_SCL = I2C_NEW_SCL;
	I2C_LAST_SDA = I2C_NEW_SDA;
	I2C_NEW_SCL  = SCL;
	I2C_NEW_SDA  = SDA;	

	if(I2C_BIT_ON){
		if(I2C_NEW_SCL!=I2C_LAST_SCL)	I2C_TIME = 0;
		else{
				I2C_TIME++;
				if(I2C_TIME==255)I2C_BIT_ON=0;
		}
	}	


	if(I2C_LAST_SCL == 1 && I2C_NEW_SCL == 1){					//start|stop condition		
 		if(I2C_LAST_SDA == 1 && I2C_NEW_SDA == 0){				//start condition			
			I2C_CLK 	= 0;
			I2C_DAT		= 0;
			I2C_NBYTE   = 0;
			I2C_BIT_ON 	= 1;
			I2C_BIT_ADR	= 1;
			I2C_BIT_RD	= 1;
			I2C_BIT_WR	= 0;			
		}
		if(I2C_LAST_SDA == 0 && I2C_NEW_SDA == 1){				//stop condition
			I2C_BIT_ON 		= 0;
		}
	}

	
	//Clock up
	if(I2C_BIT_ON && I2C_LAST_SCL == 0 && I2C_NEW_SCL == 1){	
		I2C_CLK++;

		//Read Data : Getting Data
		if(I2C_BIT_RD && I2C_CLK!=9)
		{	
			if(I2C_CLK==1){I2C_DAT = 0;}

			if(SDA==1){
				char tmp   = 8-I2C_CLK;
				char tmp2  = 1<<tmp;
				I2C_DAT   += tmp2;
			}
		}
		
		//Write data : waiting for ACK
		if(I2C_BIT_WR && I2C_CLK == 9){
			I2C_BIT_ACK = !SDA;
			I2C_BIT_WR  = 0;
		}
	}
		
	//Clock down
	if(I2C_BIT_ON && I2C_LAST_SCL == 1 && I2C_NEW_SCL == 0){		

		//End of one Byte : Reset the Timer and Look for what is the next byte
		if(I2C_CLK==9){
			I2C_CLK = 0;
			I2C_Slave_Action();
		}


		//Writing : Getting data
		if(I2C_BIT_WR){
			// Free the line for ACK
			if(I2C_CLK==8){				
				TRISA.bitSDA = 1;			
				return;
			}

			TRISA.bitSDA = 0;			
			char tmp    = 7-I2C_CLK;
			char tmp2   = 1<<tmp;
				 tmp    = I2C_DAT & tmp2;
			SDA 		= (tmp != 0);
		}

		//Reading : Send the ACK
		if(I2C_BIT_RD && I2C_CLK==8){
	
			TRISA.bitSDA = 0;
			SDA     	 = 0;						// Send the ACK			

			if(I2C_BIT_ADR){				
				I2C_ADR 	= I2C_DAT;				 
				I2C_BIT_ADR = 0;
				SDA     	= !I2C_Slave_PIC_Adress();	// Send the ACK
			}				
		}
	}

	clrwdt();

}