The message Interpretation function interpretates message coming from MCAD.
It
exist out of two parts. The first part called "Interp_Message" is the
main part. The second part called "SubInterp_Message" is the part
dealing with LM628 commands. This is done because in the main part there are two
commands dealing with the shutter LM and the filter LM. This way we only need to
code this bit ones because the only difference is the address selection of the
boards.
All the commands stated in the document INT-PF13 are coded in here.
See that document before you go on.
I'm not gone explain every command in
here this goes behond the scope of this page.
This function is based on the "switch"
"case" contruction. The first thing we do in here is disable the
serial interrupt. If MCAD tries to send something then that is bad luck. The
protocol say's it's a synchronisched communication protocol inwhich case MCAD
always has to wait for response or either his internal timeout. I also reset the
control-bus signals in the beginning, this is just done for security reasons. We
can do it here because Interp_Message is also an defined output position. Then
it check to see if a message has been received and check OK. This is done by
reading the flag "MessageRec". If this flag is not set then we leave
from here otherwise I try to find out what the message is and do then the
propriate actions needed to execute the command. I'm not gone explain every
command executed from here. Some of them are that easy that explanation won't be
needed.
Interp_Message is reading his information out of the structure "ReceivedInfo"
in which the receiving function has written the information coming from MCAD.
The first information comes out of ReceivedInfo member MechName. In this field
is were you find the first command. The second information is information about
the SubCommand and the member is called MechAction. The rest are normally
Arguments and are in the member "Argument". For how the structure is
defined see Declarations.
/*****************************************************************************/ /* FunctionName : SubInterp_MEssage */ /* FunctionInput : NONE. */ /* FunctionOutput : NONE. */ /* FunctionCall : NONE. */ /* CommonVarUse : NumOfChars. */ /* StructureUse : SendInfo & ReceivedInfo. */ /* Description : This function is a sub function from interpretetad Mess. */ /* : It is made seperated because its used by the Shutter and */ /* : Filterwheel. Therefor in Interpretate message (the main */ /* : one) only sets the address right. The rest is done here. */ /* : Inhere you find 15 out of the 23 LM628 Commands. */ /* : One extra command is added to readback (MCAD) the calcu */ /* : lated breakpoints. This is not a LM628 command. */ /* LastUpdates : 02/10/96. */ /*****************************************************************************/ void SubInterp_Message(void) { SendInfo.ACK[0]=Ack; NumbOfChars=0; switch (ReceivedInfo.MechAction[0]) { case RESET: /* Reset Command LM628 */ ReSet(); break; case DFH : Dfh(); /* Define Home */ break; case SIP : Sip(); /* Set Index Position */ break; case SBPA : /* Set Breakpoint Absolute */ act.breakpoint = ReceivedInfo.Argument[0]; act.breakpoint = act.breakpoint << 8; act.breakpoint = act.breakpoint | ReceivedInfo.Argument[1]; act.breakpoint = act.breakpoint << 8; act.breakpoint = act.breakpoint | ReceivedInfo.Argument[2]; act.breakpoint = act.breakpoint << 8; act.breakpoint = act.breakpoint | ReceivedInfo.Argument[3]; Sbpa(); break; case LTRJ : Ltrj(); /* Load Trajectory */ break; case RSTI : Rsti(); /* Reset Interrupts */ break; case STT : Stt(); /* Start Motion */ break; case LFIL : /* Load Filter Values */ act.dersample=ReceivedInfo.Argument[0]; act.whichload=ReceivedInfo.Argument[1]; act.kp=ReceivedInfo.Argument[2]; act.kp=act.kp << 8; act.kp=act.kp | ReceivedInfo.Argument[3]; act.ki=ReceivedInfo.Argument[4]; act.ki=act.ki << 8; act.ki=act.ki | ReceivedInfo.Argument[5]; act.kd=ReceivedInfo.Argument[6]; act.kd=act.kd << 8; act.kd=act.kd | ReceivedInfo.Argument[7]; act.il=ReceivedInfo.Argument[8]; act.il=act.il << 8; act.il=act.il | ReceivedInfo.Argument[9]; lfil(); break; case UDF : Udf(); /* Udate Loaded Filter Values */ break; case RDSIGS : Rdsigs(); /* Read Signals */ NumbOfChars=2; SendInfo.Argument[1] = act.sigs & 0xff; SendInfo.Argument[0] = (act.sigs >>8) & 0xff; break; case RDSUM : Rdsum(); NumbOfChars=2; SendInfo.Argument[1] = act.intsum & 0xff; SendInfo.Argument[0] = (act.intsum >>8) & 0xff; break; case RDRV : Rddv(); /* Read Desired Velocity */ NumbOfChars=4; SendInfo.Argument[3] = act.desvel & 0xff; SendInfo.Argument[2] = (act.desvel >>8) & 0xff; SendInfo.Argument[1] = (act.desvel >> 16) & 0xff; SendInfo.Argument[0] = (act.desvel >> 24) & 0xff; break; case RDIP : Rdip(); /* Read Index Position */ NumbOfChars=4; SendInfo.Argument[3] = act.index & 0xff; SendInfo.Argument[2] = (act.index >>8) & 0xff; SendInfo.Argument[1] = (act.index >> 16) & 0xff; SendInfo.Argument[0] = (act.index >> 24) & 0xff; break; case RDDP : Rddp(); /* Read Desired Position */ NumbOfChars=4; SendInfo.Argument[3] = act.desired & 0xff; SendInfo.Argument[2] = (act.desired >>8) & 0xff; SendInfo.Argument[1] = (act.desired >> 16) & 0xff; SendInfo.Argument[0] = (act.desired >> 24) & 0xff; break; case RDRP : Rdrp(); /* Read Real Position */ NumbOfChars=4; SendInfo.Argument[3] = act.realpos & 0xff; SendInfo.Argument[2] = (act.realpos >>8) & 0xff; SendInfo.Argument[1] = (act.realpos >> 16) & 0xff; SendInfo.Argument[0] = (act.realpos >> 24) & 0xff; break; case BPR : /* Send BreakPoint Values */ NumbOfChars=8; Help = ShutOpenPulses; SendInfo.Argument[3] = Help & 0xff; SendInfo.Argument[2] = (Help >> 8) & 0xff; SendInfo.Argument[1] = (Help >> 16) & 0xff; SendInfo.Argument[0] = (Help >> 24) & 0xff; Help = ShutClosePulses; SendInfo.Argument[8] = Help & 0xff; SendInfo.Argument[7] = (Help >> 8) & 0xff; SendInfo.Argument[6] = (Help >> 16) & 0xff; SendInfo.Argument[5] = (Help >> 24) & 0xff; break; default: SendInfo.ACK[0]=Nack; break; } return; } /*===========================================================================*/ /* FunctionName : Interpeted Messages */ /* FunctionInput : NONE. */ /* FunctionOutput: NONE. */ /* FunctionCall : Calc_Degree_Pulses_F_W, Write_Address, Find_Index, Rdip, */ /* : stscpy, Sys_Req_Init, SunInterp_Message, Rsti, Detent_Task*/ /* : Read_Switches, Sbpa, Mski, Read_Detent_Status, Turn_Off, */ /* CommonVarUse : SignalData, TimeoOut, ShutOpenPulses, ShutClosePulses, */ /* : NumbOfChars, ExposureTimingOpen, ExposureTimingClose. */ /* : MessageRec, switches, Guarding, TransmitStatus. */ /* StructureUse : */ /* Description : Main is always the start_point from here we call first */ /* : some other functions to initialies the system. */ /* : */ /* : */ /* LastUpdated : ../../96 [.... Test] */ /*===========================================================================*/ void Interp_Message(void) { unsigned char xdata detentdata[4]; unsigned long xdata ShutOpenHelp, ShutCloseHelp, HelpIndex; ES=0; /* No Serial Interrupts exepted */ TI=0; /* Nothing to transmit yet */ SignalData=0x18; /* Default for Electronics Signals */ P1=SignalData; /* In case it's overwritten somewhere */ TimeOut=0; /* TimeOut set to Zero ........ */ if (MessageRec) /* A Message Recived ? */ { switch (ReceivedInfo.MechName[0]) /* Yes, check for which mech. */ { case Micro : /* Micro as whole ? */ SendInfo.ACK[0]=Ack; switch (ReceivedInfo.MechAction[0]) { case RST : Sys_Req_Init(); NumbOfChars=0; SendInfo.ACK[0]=Ack; break; case ZeroSet : EX1=0; /* Prefent from Interrupt */ ShutOpenHelp=ShutOpenPulses; ShutCloseHelp=ShutClosePulses; ShutOpenPos[0]=ReceivedInfo.Argument[0]; ShutOpenPos[1]=ReceivedInfo.Argument[1]; ShutOpenPos[2]=ReceivedInfo.Argument[2]; ShutOpenPos[3]=ReceivedInfo.Argument[3]; ShutClosePos[0]=ReceivedInfo.Argument[4]; ShutClosePos[1]=ReceivedInfo.Argument[5]; ShutClosePos[2]=ReceivedInfo.Argument[6]; ShutClosePos[3]=ReceivedInfo.Argument[7]; Calc_Degree_Pulses_F_W (); TimeOutSet=15000; TR0=1; stscpy(ShutterToAct); Address=ShutterAddress; Write_Address(); Find_Index(); Rdip(); HelpIndex=act.index-ShutOpenPulses; SendInfo.Argument[3] = HelpIndex & 0xff; SendInfo.Argument[2] = (HelpIndex >>8) & 0xff; SendInfo.Argument[1] = (HelpIndex >> 16) & 0xff; SendInfo.Argument[0] = (HelpIndex >> 24) & 0xff; stscpy(ActToShutter); stscpy(FilterToAct); Address=FilterAddress; Write_Address(); Find_Index(); Rdip(); HelpIndex=act.index-ShutClosePulses; SendInfo.Argument[7] = HelpIndex & 0xff; SendInfo.Argument[6] = (HelpIndex >>8) & 0xff; SendInfo.Argument[5] = (HelpIndex >> 16) & 0xff; SendInfo.Argument[4] = (HelpIndex >> 24) & 0xff; stscpy(ActToFilter); NumbOfChars=8; ShutOpenPulses=ShutOpenHelp; ShutClosePulses=ShutCloseHelp; break; case Syn : NumbOfChars=0; break; default: SendInfo.ACK[0]=Nack; break; } break; case ShutterWheel : /* Sub Commands Are The LM628 Commands */ Address = ShutterAddress; Write_Address(); stscpy(ShutterToAct); SubInterp_Message(); stscpy(ActToShutter); Rsti(); break; case FilterWheel : /* Sub Commands Are The LM628 Commands */ Address=FilterAddress; Write_Address(); stscpy(FilterToAct); SubInterp_Message(); stscpy(ActToFilter); break; case Detent : /* Detent action */ Address = DetentAddress; Write_Address(); NumbOfChars=0; TimeOutSet=500; TR0=1; switch (ReceivedInfo.MechAction[0]) { case In_Det : Detent_Task(In_Det); SendInfo.ACK[0]=Ack; break; case Out_Det : Detent_Task(Out_Det); SendInfo.ACK[0]=Ack; break; case State_Det : Read_Data(1, detentdata); SendInfo.Argument[0]=detentdata[0]; NumbOfChars=1; SendInfo.ACK[0]=Ack; break; default: SendInfo.ACK[0]=Nack; break; } break; case FilterSwitch : TimeOutSet=500; TR0=1; switch (ReceivedInfo.MechAction[0]) { case State_Switch : NumbOfChars=1; SendInfo.ACK[0]=Ack; Address = SwitchAddress; Write_Address(); Read_Switches(); if(switches == 0x01) { SendInfo.Argument[0]=Enable; } else { SendInfo.Argument[0]=Reset; } SendInfo.Argument[0]=switches; break; default: SendInfo.ACK[0]=Nack; break; } break; case ExposureTime : TimeOutSet=500; TR0=1; switch (ReceivedInfo.MechAction[0]) { case Define : ShutClosePos[0]=ReceivedInfo.Argument[0]; ShutClosePos[1]=ReceivedInfo.Argument[1]; ShutClosePos[2]=ReceivedInfo.Argument[2]; ShutClosePos[3]=ReceivedInfo.Argument[3]; ShutOpenPos[0]=ReceivedInfo.Argument[4]; ShutOpenPos[1]=ReceivedInfo.Argument[5]; ShutOpenPos[2]=ReceivedInfo.Argument[6]; ShutOpenPos[3]=ReceivedInfo.Argument[7]; /* ShutClosePos[0]=0x00; ShutClosePos[1]=0x03; ShutClosePos[2]=0xd0; ShutClosePos[3]=0x90; ShutOpenPos[0]=0x00; ShutOpenPos[1]=0x01; ShutOpenPos[2]=0xe8; ShutOpenPos[3]=0x48; */ Calc_Degree_Pulses(); /* Calculate Degrees to Position */ NumbOfChars=0; /* No characters to send */ SendInfo.ACK[0]=Ack; /* Only an Acknowledge to sys */ break; case Zero : ExposureTimingOpen = 0L; /* Reset the open timing */ ExposureTimingClose = 0L;/* Reset the close timing as well*/ THTL2=0L; HelpVariable=0L; TH2=0; TL2=0; OpenFlag=1; /* Next move is to Open */ Address=ShutterAddress; /* We gone talk to the shutter */ Write_Address(); /* Yes, we do */ stscpy(ShutterToAct); /* Use the shutter structure */ act.breakpoint=ShutOpenPulses; Sbpa(); /* Store breakpoint into LM628 */ stscpy(ActToShutter); /* Set back what we've used */ Address=ShutterAddress; Write_Address(); Mski(); T2I0 = 1; /* Start Timer 2 */ EX1=1; /* Enable Interrupt for LM628 */ NumbOfChars=0; SendInfo.ACK[0]=Ack; /* Let sys know its all done */ break; case State_Ex : NumbOfChars=8; Help = ExposureTimingOpen * 20; HelpVariable = Help; SendInfo.Argument[3] = HelpVariable & 0xff; HelpVariable = Help; HelpVariable = HelpVariable >> 8; SendInfo.Argument[2] = HelpVariable & 0xff; HelpVariable = Help; HelpVariable = HelpVariable >> 16; SendInfo.Argument[1] = HelpVariable & 0xff; HelpVariable = Help; HelpVariable = HelpVariable >> 24; SendInfo.Argument[0] = HelpVariable & 0xff; Help = ExposureTimingClose * 20; HelpVariable = Help; SendInfo.Argument[7] = HelpVariable & 0xff; HelpVariable = Help; HelpVariable = HelpVariable >> 8; SendInfo.Argument[6] = HelpVariable & 0xff; HelpVariable = Help; HelpVariable = HelpVariable >> 16; SendInfo.Argument[5] = HelpVariable & 0xff; HelpVariable = Help; HelpVariable = HelpVariable >> 24; SendInfo.Argument[4] = HelpVariable & 0xff; SendInfo.ACK[0]=Ack; break; default: NumbOfChars=0; SendInfo.ACK[0]=Nack; break; } break; case FilterAccess : TimeOutSet=500; TR0=1; SendInfo.ACK[0]=Ack; switch (ReceivedInfo.MechAction[0]) { case State_Filt : NumbOfChars = 1; Address = DetentAddress; Write_Address(); Read_Detent_Status(); if(detentstatus & 0x08) { FiltDoorOpen=1; SendInfo.Argument[0]=NULL; } else { FiltDoorOpen=0; SendInfo.Argument[0]=Enable; } break; case Guard : NumbOfChars=0; if (ReceivedInfo.Argument[0]) { Guarding = 1; if (FiltDoorOpen) { Address = FilterAddress; Write_Address(); Turn_Off_Ltrj(); } } else Guarding = 0; break; default: SendInfo.ACK[0]=Nack; break; } break; } TransMitStatus=1; /* Messsage ready for transmitting */ } TR0=0; /* Stop Timer */ TimeOutSet=0; TimeOut=0; MessageRec = 0; /* Wait for new message */ ES=1; /* Exept messages agian */ TI=1; /* We have to transmit something */ return; }