Communication Function.


The communications function is partly an interrupt driven function. It's using interrupt number 4 and registerset number 3 of the 80535 processor.
If it receives an interrupt it tries to find-out who was interrupting. It can either be the send (TI bit) or receive (RI bit). The whole communication part exist out of 4 parts.
The first part is the so called Communication_Interface which deals with the interrupt's. The second part part is the so called "Receive_Char" function which is grabbing the characters coming from MCAD. The thrid part so called "TransMit_Char" deals with sending characters to MCAD. It includes also an standard function so called "Putchar". This function has slitly changed and is therefore included as seperad source file which you can find in the same directory as the progam "MCAM".
The last bit is the so called "Calc_CheckSum" function which does a simple calculation to add a checksum byte to the message or check the checksum if it has received an message.


The function "Communication_Interface"

It is only possible to get into this function by receiving an interrupt. The function then first looks to see if it is an RI interrupt which means that we have received an character from MCAD. If it has recieved an charachter it then set the "TransMitStatus flag to zero. This is done because the communication protocol is a synchroniced protocol. Meaning if MCAD sends then we are not alowed to send or visa versa. Then we check to findout if we already have received the control-byte from MCAD. If so that then means that the rest of the characters are coming in. So you see that we only allow the system to interrupt twice. After that we go to the function Recieve_Char to receive the rest. I could have done it all under interrupt control but ones we get the control-byte from MCAD we then will receive more. And the system is normally not busy with doing anything else. If all the characters needs to be interrupt driven then we need to created an pointer to keep track of where we are in receiving characters. In Receive_Char you will see that we use the value count for receiving characters which comes from MCAD.
If the interrupt was a TI interrupt then I first see if we have to send something by checking the flag TransMitStatus. If these both are true then we have to send and therefore go into TransMit_Char(variable) to send what we have to send.


FlowChart of Communication_Interface.



Listing of Communication_Interface


/*===========================================================================*/
/* FunctionName  : Communication_Interface.                                  */
/* FunctionInput : SBUF via Interrupt.                                       */
/* FunctionOutput: NONE.                                                     */
/* CommonVarUse  : TransMitStatus, SBUF                                      */
/* StructureUse  : ReceiveInfo.                                              */
/* Description   : This function is an interrupt drive function. It checks   */
/*               : weather it needs sending or receiving.                    */
/* LastUpdated   : ../../96 [.... Test]                                      */
/*===========================================================================*/
#pragma NOAREGS
void Communication_Interface(void) interrupt 4 using 3
{


   unsigned char xdata Edit;

  if (RI)                                 /* See if received something      */
    {
     TransMitStatus=0;                    /* No transmition allowed         */
     if (ReceivedInfo.ControlByte[0])     /* Received control byte ?        */
        {
         ES=0;                            /* Disable Interrupt on Serial    */
         TimeOutSet = 500;                /* TimeOut using 500 mSec.        */
         Receive_Char();                  /* Get the rest of it.            */
         ES=1;                            /* Interrupts allowed             */
        }
     else
       {
      Edit=SBUF;                          /* Get character from SBUF        */
        if (Edit & 0xc0 )                 /* Yes, got you.                  */
          {
           ReceivedInfo.ControlByte[0]=Edit;
          }
       }
     ES=1;                                /* Enable transmitting.           */
     RI=0;                                /* Get ready for next Byte        */
    }
  if (TransMitStatus)                    /* Something to send ?             */
    {
     ES = 1;                             /* If so enable transmitting       */
     TransMit_Char(NumbOfChars);	 /* OK, we need transmitting        */
    }
return;
}
#pragma AREGS

The function "Receive_Char"



FlowChart of Receive_Char.



/*==============================*/
/* FunctionName  : Receive Character.                                        */
/* FunctionInput : None.                                                     */
/* FunctionOutput: None.                                                     */
/* CommonVarUse  :                                                           */
/* StructureUse  : ReceivedInfo.                                             */
/* Description   : The first to byte's are read separed, the Argument are    */
/*               : read through a loop. The loop information comes from SYS  */
/*               : (mum) and is hidden into the controlbyte.                 */
/*               : Getkey is a standard Lib. function but is changed due to  */
/*               : us timeouts.                                              */
/* LastUpdated   : ../../96 [.... Test]                                      */
/*===========================================================================*/
void Receive_Char(void)
{
  int xdata Counter, xdata Counter1;
  unsigned char xdata ChkSum;
  char  *Pointer;

  ReceivedInfo.MechName[0] = _getkey();        /* Second Byte is Mech. Name    */
  ReceivedInfo.MechAction[0] = _getkey();      /* Third Byte is Action on Mech.*/
  Counter=ReceivedInfo.ControlByte[0] & 0x3f;  /* Get counter for bytes to Rec.*/
  NumbOfChars=Counter;
  for (Counter1=0; Counter1 < (Counter-2); Counter1++)  /* Sys has said so...    */
    {
     ReceivedInfo.Argument[Counter1] = _getkey(); /* Get arguments for Mech or */
    }
  ReceivedInfo.CheckSum[0] = _getkey();        /* Last byte is Checksum        */
  MessageRec = 1;                              /* Set for interpetation        */
  Pointer=&ReceivedInfo.MechName[0];           /* Create pointer for CheckSum  */
  ChkSum = Calc_CheckSum(&ReceivedInfo.MechName[0]); /* Calculate Checksum     */
  if (ChkSum != ReceivedInfo.CheckSum[0])      /* Check if equal               */
    {
     SendInfo.ACK[0]= Nack;                    /* Sys wants NACK if not        */
     TransMitStatus = 1;                       /* Make Sure SYS receives NACK  */
     MessageRec = 0;                           /* Prefent for interpetation    */
     Clear_ReceivedInfo();                     /* Clear Received Messages      */
     NumbOfChars=0;                            /* Nothing Received Well        */
    } 
ReceivedInfo.ControlByte[0] = Reset;           /* All Received wait for next   */
return;
}

The function "TransMit_Char"


This function makes sure that all characters in the Transmit Buffer will be send to MCAD. On entry we first get the number of characters to send. This number is also used for calculating the Checksum which is the second step in this function. After the calculation has been done we then trigger MCAD with the first Character, either a NACK or an ACK.The Third step is to send the arguments if any. The last step is to send the Checksum byte over. On exit we clear the buffer and resetting some flags.


FlowChart of TransMit_Char.



Listing of TransMit_Char.


/*========================================================================================================================*/
/* FunctionName  : TransMitting Characters                                   */
/* FunctionInput :                                                           */
/* FunctionOutput:                                                           */
/* CommonVarUse  :                                                           */
/* StructureUse  :                                                           */
/* Description   :                                                           */
/*               :                                                           */
/*               :                                                           */
/*               :                                                           */
/*               :                                                           */
/* LastUpdated   : ../../96 [.... Test]                                      */
/*===========================================================================*/
void TransMit_Char(int CharsToSend)

{ int xdata Counter;

  NumbOfChars=NumbOfChars+1;

  SendInfo.CheckSum[0] = Calc_CheckSum(&SendInfo.ACK[0]);
  putchar (SendInfo.ACK[0]);         /* Send ACK or NACK as first               */

  NumbOfChars=NumbOfChars-1;

  for (Counter=0; Counter < CharsToSend; Counter++)
     {
	putchar (SendInfo.Argument[Counter]);  /* Send Character SBUF out     */     
     }
  putchar (SendInfo.CheckSum[0]); /* They want CheckSums as well, why ?      */
  TransMitStatus = 0;             /* All send so stop Sending                */
  Clear_SendInfo();               /* Clear Structure for Re-use              */
  NumbOfChars=0;                  /* Nothing left to send                    */
  ES=1;
return;
}



The function "Calc_Checksum."


The function to Calculate a Checksum is added because of some secure way to communicated. This is only a 8 bit checksum and it adds just all values in the Send buffer or in the Receive Buffer. The only variable past on to this function is a pointer which points to the message of which we have to calculate the Checksum. If the Checksum passes the 8-bit max. value then we just ignore the most-significant value.


FlowChart of Calc_Checksum.



/*===========================================================================*/
/* FunctionName  : Calculate Checksum                                        */
/* FunctionInput :                                                           */
/* FunctionOutput:                                                           */
/* CommonVarUse  :                                                           */
/* StructureUse  :                                                           */
/* Description   :                                                           */
/*               :                                                           */
/*               :                                                           */
/*               :                                                           */
/*               :                                                           */
/* LastUpdated   : ../../96 [.... Test]                                      */
/*===========================================================================*/
unsigned char Calc_CheckSum (char *Pointer)

{
 unsigned char xdata ChkSum;
 int xdata Counter;

 ChkSum=0;
 for (Counter=0; Counter < NumbOfChars; Counter++)
    {
     ChkSum = ChkSum + *Pointer++;
    } 
return ChkSum;
}

Back to Index page.