
/*****************************************************************************/
//			************* MASTER CARD CODE *************
/*****************************************************************************/

#define SP_START_BIT	0xCE
#define SP_END_BIT		0xCC
#define END_OF_COMM		0xCB
#define ACKNOWLEDGE		0xCA
#define DATA_ACK		0xC8

unsigned char buf;
unsigned char end_of_comm;
unsigned char synch_flag;

bit acknowledge;
bit data_ack;
bit transmit_ready;

void SerialISR_Master(void) interrupt 4 using 3
{	/*Data Reception*/  
	if(RI)					
	{	// RI = 1, means data received from addressed slave
		buf = SBUF; // Store The Character Sent From Slave In Buffer

		if((buf ==  ACKNOWLEDGE))
		{	//If Data Received Is Acknowledge Type...
			acknowledge = 1;// Set Acknowledge Received Flag
		}
		else if(buf == DATA_ACK)//If Data Received Is 'Data Acknowledge'...
			data_ack = 1;// Set Data Acknowledged Flag

		else if((buf & 0XF0) == 0XA0)  
		{	// Cross Check The End Of Comm Signal Is Received From The Proper Slave Or Not
			end_of_comm = 0XCC;   // Set The End Of Communication Flag
		}
		else if(buf == SP_END_BIT)  
		{	//If Data Received Is Slave Portocol End Flag...	
			
			/*Process the received data operations*/

			transmit_ready = 0;		//	Block The Transmitter Ready Token
			TB8 = 0;				//	Clear Bit 8 Of Comm               
			SBUF = DATA_ACK;        //	Send The Data Acknowledge to Slave         	
        }
		else if(buf == SP_START_BIT) 
		{	//If Data Received Is Slave Protocol Start Byte	

			/*Prepare to receive the Data bytes from the next reception*/

			transmit_ready = 0;		//	Block The Transmitter Ready Token
			TB8 = 0;				//	Clear Bit 8 Of Comm               
			SBUF = DATA_ACK;        //	Send The Data Acknowledge to Slave                 
		}
	    else
		{	//If Data Bytes Are Being Received...
			
			/*Load the data bytes into the buffers*/

			transmit_ready = 0; //	Block The Transmitter Ready Token   
			TB8 = 0;			//	Clear Bit 8 Of Comm                      
			SBUF = DATA_ACK;    //  Send The Data Ack On Every Data Received 
		}	
		RI = 0;		//	Clear Ri To Wait For Next Character   
		buf = 0;	//	Clear The Received Byte Storing Buffer
	}
	/*Data Transmission*/
	else if(TI) 
	{	// TI = 1, means ready to load new character in SBUF
		TB8 = 0;// clear bit 8, for general data transmission
		TI = 0;	// clear TI flag since we are going to transmit again
		transmit_ready = 1;	// release the transmitter ready token after transmission completed
	}
}

bit enableSlaveToTx(unsigned char sid)
{
	transmit_ready = 0;		// take transmitter ready token in order to transmit
	acknowledge    = 0;
	TB8 = 1;				// set bit 8, for address transmission
	SBUF = sid;				/* General Broadcast address - all slaves receive this */
	synch_flag = 75;		// Load The Synchronisation Flag Count, which counts down in TISR every 20 ms
	while( (!acknowledge) && synch_flag){;}
	if(!acknowledge)
	{	
		return 0;
	}
	acknowledge = 0;     // If It Responds Go Further
 	return 1;
}	

void getDataFromSlaves(void)
{
	unsigned char slave_card_id;

	for(slave_card_id=0;slave_card_id<13;slave_card_id++)
	{
		if(end_of_comm == 0X55)						
		{	// If Comm Port Is Free...
			end_of_comm = 0XAA;//MAKE IT BUSY
			if(enableSlaveToTx(slave_card_id))
			{	// If The Addressed Slave Is Enabled For Transmitting Mode...
				synch_flag = 75;	// Load The Synchronisation Flag Count, which counts down in TISR every 20 ms
				while( (end_of_comm == 0XAA) && synch_flag){;}
				// Wait Until The Slave Transmits The Total Data Or Synch Count Comes To Zero thro Timer 0 ISR
				if(end_of_comm == 0XAA)			
				{	// If The Slave Card Lost The Communication

					/*Error Log storing code goes here*/
				}
				end_of_comm = 0x55;// Make Comm Port Free...
			}
			else									
			{	// If The Addressed Slave Does Not Respond At All...
				/*We give 5 turns for the slave to respond. If it fails, we
				  store the Error Log and send reset signal to restart the system.
				  else,
				*/
				end_of_comm = 0x55;// Make Comm Port Free...
			}
		}
	}
}
void main(void)
{

	/*Initialisations go here*/
	while(1)
	{
		getDataFromSlaves();
		/*Remaining code goes here*/
	}
}

/*****************************************************************************/
//			************* 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

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;

void send_data(unsigned char i) 
{
	trans_r = 1;
	SBUF = i;                      // SEND THE DATA TO THE MASTER 
	while(trans_r);	
}

void sendProtocolToMaster(void)
{
	/*
	Data bytes sending code goes here.
	Each byte requires acknowledge from master (DATA_ACK)
	*/
	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;
	}
}

