/*****************************************************************************/
//			************* SLAVE CARD CODE *************
/*****************************************************************************/

#define MP_START_BIT   		0XCF	/* Master Protocol Start				*/ 
#define SP_START_BIT   		0xCE	/* Slave  Protocol Start				*/ 
#define MP_END_BIT	        0xCD	/* Master Protocol End					*/ 
#define SP_END_BIT          0xCC	/* Slave  Protocol End					*/ 
#define ACKNOWLEDGE	        0xCA	/* Acknowledge From Slave Card			*/ 
#define DATA_ACK        	0xC8	/* Data Acknowledge						*/ 
#define OH_START_BIT        0xB1	/* Onhook / Offhook On Extensions		*/ 

unsigned char code END_OF_COMM_ARR[12]=/*Used for identifying unique End Of Comms at Master End*/
		{0XA0,0XA1,0XA2,0XA3,0XA4,0XA5,0XA6,0XA7,0XA8,0XA9,0XAA,0XAB};

bit give_ack;		/* Send Acknowledge To Master */     
bit give_data_ack;	/* Send Data Acknowledge To Master */
bit transmit_enable;/* Slave Is Data Receiver Or Re-Transmitter */
bit trans_r;		/* Transmitter Ready Flag */               
bit data_ack;		/* Data Acknowledge Received Flag */       
bit data_ready;		/* Data Ready To Be Sent To Master Flag */ 

unsigned char hardware_id;	/* 0x00 ~ 0x0B */
unsigned char rec_data;		/* Data Received Buffer */ 
unsigned char off_hook;		/* Status Buffer */        

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( ( (rec_data & 0xf0) == 0x20) || ( (rec_data & 0xf0) == 0x10) ) 
			{	// IF THE MODE IS RECEIVER / RE-TRANSMITTER	
				if(hardware_id == (rec_data & 0x0F)) 		
				{	/* If Received Correct Address */
					transmit_enable = (rec_data & 0x20); //UPDATE THE RECEIVER / RE-TRANSMITTER FLAG
					SM2 = 0;/* Prepare To Receive The Data Bytes That Will Be Coming */
					give_ack = 1; /* Send Ack Signal To Master */
			  	}
				else 
				{SM2 = 1;}/* Make This Slave As Not Being Addressed */ 		
			}
			else
			{	/* If The Addressed Slave Is Not This...*/  
			    SM2 = 1;/* Make This Slave As Not Being Addressed */  
			}
			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 Master Portocol End Byte */	
				/* 
					Update The Protocol Data 
				*/        
			}
			else if(rec_data == MP_START_BIT) 
			{	/* If Data Received Is Master Protocol Start Byte */	       
				/*
					Prepare To Receive The Data Bytes From The Next Reception
				*/
			}
			else
			{	/* If Data Bytes Are Being Received...*/     
				/*
					Load The Data Bytes Into The Buffers
				*/   
			}	
			give_data_ack = 1;/* Send Data Acknowledge To Master */
		}		
		RI = 0;			/* Clear RI To Wait For Next Character */ 
		rec_data = 0;	/* Clear The Received Byte Storing Buffer */
	}
	// TRANSMITTER SECTION
	if(TI)					
	{							
		TI = 0;		
		trans_r =0;
	}
}

void send_data(unsigned char i) 
{	/* Send The Data Byte To The Master */
	trans_r = 1;
	SBUF = i;                       
	while(trans_r);	
}

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)
{	/* Updates The All The Current Onhook/Offhook Status Of The Slave */
	if(data_ready)
	{									
		send_data_w_ack(SP_START_BIT);	/* Send Slave Protocol Start Byte */
		send_data_w_ack(OH_START_BIT);	/* Send 'Protocol Type' Identification Byte	*/
		send_data_w_ack(off_hook);		/* Send The Data Byte */
		send_data_w_ack(SP_END_BIT);	/* Send Slave Protocol End Byte	*/
		data_ready = 0;
	}
	send_data(END_OF_COMM_ARR[hardware_id]);/* Send The End Of Comm Byte */
	transmit_enable = 0; 
	SM2 = 1;             
}

void main (void)
{
	/* Initialisation Code Here */
	/* Card hardware ID Calculation Code Here */
	while(1)
	{	/* Loop Forever */
		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 Data Ack */								                                                                                          
				give_data_ack = 0;/* Clear The Request */                                                                      
				send_data(DATA_ACK);	                                                                                          
			}							                                                                                          
			if(transmit_enable)//If The Slave Is Enabled In Re-Transmiting Mode,			                                                                                          
				sendProtocolToMaster();// Send Pending Data To The Master.     
		}	
	}
}

