

/*****************************************************************************/
//			************* SLAVE CARD CODE *************
/*****************************************************************************/

#define MP_START_BIT      		0XCF 
#define MP_END_BIT       		0xCD
#define ACKNOWLEDGE		   		0xCA
#define DATA_ACK           		0xC8
#define RESET_SLAVE_SIGN		0XC7

#define OH_START_BIT        	0xB1

unsigned char code END_OF_COMM_ARR[13]=/*Used for identifying unique End Of Comms at Master End*/
		{0XA0,0XA1,0XA2,0XA3,0XA4,0XA5,0XA6,0XA7,0XA8,0XA9,0XAA,0XAB};

bit restart;
bit give_ack;
bit give_data_ack;
bit transmit_enable;
bit trans_r;
bit restart;

unsigned char hardware_id;/*0000 ~ 1100 */
unsigned char rec_data;
unsigned char off_hook,temp_off_hook;

void send_data(unsigned char i) 
{	// send the data byte to the master
	trans_r = 1;
	SBUF = i;                       
	while(trans_r);	
}

/*
Sending data byte to master, and each data byte requires 
acknowledge from master
*/
void send_data_w_ack(unsigned char i) 
{	
	data_ack = 0;
	SBUF = i;
	while(!data_ack);//Wait till master acknowledge received in SISR.	
}

void sendProtocolToMaster(void)
{
	if(off_hook != temp_off_hook)
	{   //updates the all the current onhook/offhook status of the slave    
		send_data_w_ack(SP_START_BIT);			 // start of the protocol
		send_data_w_ack(OH_START_BIT);           // protocol no
		/*
		Inorder to avoid conflict with the protocol start, end unique bytes,
		we r sending this byte in 2 nibbles format.
        */
		send_data_w_ack(off_hook & 0x0f);		 // sending lower off_hook status
		send_data_w_ack((off_hook >> 4) & 0x0f); // sending upper off_hook status
		send_data_w_ack(SP_END_BIT);			 // end of the protocol
		temp_off_hook = off_hook;				 // avoiding repeated sending
	}

	send_data(END_OF_COMM_ARR[hardware_id]);
	transmit_enable = 0; 
	SM2 = 1;             
}

void main (void)
{
	/*Initialisation code here*/
	/*Card hardware ID generation code here*/

	if(!SM2)                     //CHECKING WHETHER THE SLAVE IS PERMITED TO SEND THE DATA OR NOT
	{
		if(give_ack)               //IF THERE IS A REQUEST FOR ACK  
		{
			give_ack = 0;           //CLEAR THE REQUEST 
			send_data(ACKNOWLEDGE);
		}
		if(give_data_ack)               //IF THERE IS A REQUEST FOR ACK  
		{
			give_data_ack = 0;           //CLEAR THE REQUEST 
			send_data(DATA_ACK);
		}
		if(transmit_enable)
			sendProtocolToMaster();//IF THE SLAVE IS ENABLED IN TRANSMITING MODE SEND ALL PROTOCOLS PENDING TO THE MASTER
	}	
	if(restart)
	{
		EA = 0;
		((void(code*)(void))0x0000)();//Go to location 00 of code
	}
}

void SerialISR_Slave(void) interrupt 4 using 3	
{					
	// RECEIVER SECTION
	if(RI)					
	{	// if a character is received				
		rec_data = SBUF;// read data character sent from master and store it in rec buf
		if(RB8)	// if received general broadcast address,
		{	// Global Message Reception	
			if(hardware_id == rec_data) 		
			{	// if received correct address,
				transmit_enable = 1;
				SM2 = 0;	// prepare to read data
				give_ack = 1; // SEND ACK SIGNAL TO MASTER
			}
			else 
				SM2 = 1;// reset serial port for address reception mode			
			// This message is not acknowledged back to the Master
			// since all the slaves would be replying it at the same time
			// and the data would therefore be corrupted.
		    else if(rec_data == RESET_SLAVE_SIGN)/*To restart the slave*/
				restart = 1;

			else
			{// if the addressed slave is not this...
			    SM2 = 1;		// reset serial port for address reception mode
			}
			RB8 = 0;
		}
		else if(!SM2) // IF SLAVE IS IN RECEIVING MODE
		{	//Private Message data Reception
			if(rec_data == DATA_ACK)//If Data Received Is 'Data Acknowledge'...
				data_ack = 1;// Set Data Acknowledged Flag

			else if(rec_data == MP_END_BIT)  
			{	//If Data Received Is Slave Portocol End Flag...	
				
				/*Process the received data operations*/

				give_data_ack = 1;       	
			}
			else if(rec_data == MP_START_BIT) 
			{	//If Data Received Is Slave Protocol Start Byte	

				/*Prepare to receive the Data bytes from the next reception*/

				give_data_ack = 1;            
			}
			else
			{	//If Data Bytes Are Being Received...
				
				/*Load the data bytes into the buffers*/

				give_data_ack = 1;
			}	
		}		
		RI = 0;
		rec_data = 0;
	}
	// TRANSMITTER SECTION
	if(TI)					
	{				// TI = 1, means ready to load new character in SBUF					
		TI = 0;		// clear TI flag since we are goling to transmit again
		trans_r =0;
	}
}

