(**********************************************************************) (* *) (* Function: SIOP Serial Input / Output Port *) (* *) (* Creation Date: 27/Apr/92 From: NEW *) (* *) (* Author: Jeff Wright *) (* *) (* Description: *) (* ------------ *) (* This function uses 2 or 3 adjacent channels to form a uni or bi- *) (* directional serial port. It is designed to mimic the SIOP port *) (* found on some Motorola CSIC mcus, allowing the TPU to communicate *) (* with a wide variety of peripheral devices. Baud rate, msb or lsb *) (* first and clock polarity are all selectable by the user. *) (* In full configuration, three adjacent channels are used, the middle*) (* one being the clock channel which does all the work. The channel *) (* below the clock is the data input channel and the one above it the *) (* data output. Host sequence bits are used to select input, output *) (* or I/O modes. Only clock channel PRAM is used. *) (* *) (* NOTE: This function contains some critical timing paths due to the *) (* changing of channels - any future modification of this function *) (* should be done with caution and reference to the channel change *) (* resource table. *) (* *) (* Updates: By: Modification: *) (* -------- --- ------------- *) (* 11/Apr/93 JL Convert to new syntax. *) (* *) (*--------------------------------------------------------------------*) (* Standard Exits Used:- End_Of_Phase: N End_Of_Link: Y *) (* *) (* External Files included: NONE *) (* *) (* CODE SIZE excluding standard exits = 39 LONG WORDS *) (*--------------------------------------------------------------------*) (* *) (* *) (********** This Revision: 1.1 *********) (* *) (********** LAST MODIFIED: 11/Apr/93 BY: Jeff Loeliger ********) (* *) (**********************************************************************) (***************************************************************************) (*Motorola reserves the right to make changes without further notice to any*) (*product herein. Motorola makes no warranty, representation or guarantee *) (*regarding the suitability of its products for any particular purpose, nor*) (*does Motorola assume any liability arising out of the application or use *) (*of any product or circuit, and specifically disclaims any and all *) (*liability, including without limitation consequential or incidental *) (*damages. "Typical" parameters can and do vary in different applications. *) (*All operating parameters, including "Typical",must be validated for each *) (*customer application by customer's technical experts. Motorola does not *) (*convey any license under its patent rights nor the rights of others. *) (*Motorola products are not designed, intended, or authorized for use as *) (*components in systems intended for surgical implant into the body, or *) (*other applications intended to support or sustain life, or for any other *) (*application in which the failure of the Motorola product could create a *) (*situation where injury or death may occur. Should Buyer purchase or use *) (*Motorola products for any such unintended or unauthorized application, *) (*Buyer, shall indemnify and hold Motorola and its officers, employees, *) (*subsidiaries, affiliates, and distributors harmless against all claims, *) (*costs, damages, and expenses, and reasonable attorney fees arising out *) (*of, directly or indirectly, any claim of personal injury or death *) (*associated with such unintended or unauthorized use, even if such claim *) (*alleges that Motorola was negligent regarding the design or manufacture *) (*of the part. *) (*Motorola and the Motorola logo are registered trademarks of Motorola Inc.*) (*Motorola is an Equal Opportunity/Affirmative Action Employer. *) (*Copyright Motorola Inc. 1993 *) (***************************************************************************) (*()()()()()()()()()()() DATA STRUCTURE ()()()()()()()()()()()()()()()*) (* *) (* name: Written By: Location Bits: *) (* ----- ----------- --------------- *) (* CHANNEL_CONTROL CPU Parameter0 0..8 *) (* Standard channel config parameter -output/toggl*) (* *) (* START_MSB_LSB CPU Parameter0 15 *) (* Bit flag to select msb or lsb as first xfer bit*) (* 1 = msb first, 0 = lsb first. *) (* *) (* HALF_PERIOD CPU Parameter1 0..15 *) (* Half period of SIOP clk - defined in tcr1 clks *) (* *) (* BIT_COUNT TPU Parameter2 0..3 *) (* Holds the number of bits still to go. *) (* *) (* XFER_SIZE CPU Parameter3 0..3 *) (* Defines the number of bits in a transfer. *) (* *) (* DATA BOTH Parameter4 0..15 *) (* Before xfer,holds data to go, after completion *) (* holds recieved data.In progress - a mixture. *) (* *) (* *) (* HSQ1 HSQ0 Action *) (* ---- ---- ------ *) (* 0 0 Clock chan active only, no data xfer. *) (* 0 1 Clock + Dout chans active, no data recieve. *) (* 1 0 Clock + Din chans active, no data transmit. *) (* 1 1 Full bidirectional system tx & rx. *) (* *) (* hsr1 hsr0 Action *) (* ---- ---- ------ *) (* x 0 No action *) (* 0 1 No action *) (* 1 1 Initialise clock chan & start xfer. *) (* *) (* Links Accepted: NO Links Generated: NO *) (* *) (* Interrupts Generated After: Each complete xfer of XFER_SIZE bits *) (* *) (*()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()*) (*+++++++++++++++++++++ PARAMETER MACROS +++++++++++++++++++++++++++*) %macro CHAN_CONTROL_SIOP 'prm0'. %macro START_MSB_LSB_SIOP 'prm0'. %macro HALF_PERIOD_SIOP 'prm1'. %macro BIT_COUNT_SIOP 'prm2'. %macro XFER_SIZE_SIOP 'prm3'. %macro DATA_SIOP 'prm4'. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*) (*====================================================================*) (*||||||||||||||||||||| MICROCODE STARTS BELOW |||||||||||||||||||||*) (*VVVVVVVVVVVVVVVVVVVVV--------------------------VVVVVVVVVVVVVVVVVVVVV*) (**********************************************************************) (* *) (* ENTRY name: INIT_SIOP *) (* *) (* STATE(S) ENTERED: S1 *) (* *) (* PRELOAD PARAMETER : CHAN_CONTROL *) (* *) (* ENTER WHEN : HSR = %11 *) (* *) (* ACTION: Initialise channel via CHAN_CONTROL. Output 1st data bit *) (* & schedule 1st clock match. Note polarity & shift direction*) (* *) (**********************************************************************) %entry name = init_siop; start_address *; disable_match; cond hsr1 = 1, hsr0 = 1; ram p <- @CHAN_CONTROL_SIOP. init_siop: au nil := p,ccl; ram diob <- @XFER_SIZE_SIOP. If N = 1 then goto clkpol_siop; (* test shift direction bit *) chan config := p; (* setup channel from PRAM *) chan set flag1; enable_mtsr. au nil :=>> p,ccl; ram diob -> @BIT_COUNT_SIOP. chan clear flag1. clkpol_siop: If C = 0 then goto dout_siop; chan clear flag0. (* remember clock polarity *) au ert := tcr1; (* get ref for first clock edge *) ram p <- @DATA_SIOP. (* get data word *) chan set flag0. (**********************************************************************) (* *) (* ENTRY name: DOUT_SIOP *) (* *) (* STATE(S) ENTERED: S2 *) (* *) (* PRELOAD PARAMETER : DATA_SIOP *) (* *) (* ENTER WHEN : m/tsr=1, flag0 = pin *) (* *) (* ACTION: Output next data bit. Shift data reg. Schedule nxt clk edge*) (* *) (**********************************************************************) %entry name = dout_siop; start_address *; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = x,m/tsr = 1,pin = 1,flag0 = 1; ram p <- @DATA_SIOP. %entry name = dout1_siop; start_address *; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = x,m/tsr = 1,pin = 0,flag0 = 0; ram p <- @DATA_SIOP. dout_siop: If flag1 = 1 then goto tst_hsq_siop. (* which way to shift ? *) au diob :=<< p,ccl; (* msb first , or *) ram diob -> @DATA_SIOP. au diob :=>> p,ccl; (* lsb first *) ram diob -> @DATA_SIOP. tst_hsq_siop: If hsq0 = 0 then goto end_siop. (* skip data output ? *) au a := ert. au chan_reg := chan_reg + #$10. (* change to dout chan *) If C = 0 then goto out_low_siop,flush; chan tbs := out_m1_c1. If true then goto out_siop,flush; chan pin := high, disable_mtsr. out_low_siop: chan pin := low, disable_mtsr. (* output new data bit *) out_siop: au chan_reg := chan_reg + #$F0. (* change back to clock chan *) end_siop: ram diob <- @HALF_PERIOD_SIOP. au ert := a + diob; (* not done - setup next clk edge *) chan write_mer, neg_lsl, neg_tdl, neg_mrl; end. (**********************************************************************) (* *) (* ENTRY name: DIN_SIOP *) (* *) (* STATE(S) ENTERED: S3 *) (* *) (* PRELOAD PARAMETER : BIT_COUNT_SIOP *) (* *) (* ENTER WHEN : m/tsr=1, flag0 =/= pin *) (* *) (* ACTION: Input new data bit. Update bit count. Schedule nxt clk edge*) (* if bit count not zero. If zero, interrupt CPU. *) (* *) (**********************************************************************) %entry name = din_siop; start_address *; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = x,m/tsr = 1,pin = 1,flag0 = 0; ram p <- @BIT_COUNT_SIOP. %entry name = din1_siop; start_address *; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = x,m/tsr = 1,pin = 0,flag0 = 1; ram p <- @BIT_COUNT_SIOP. din_siop: au a := ert; ram diob <- @DATA_SIOP. If hsq1 = 0 then goto count_siop. (* skip data input ? *) au p := p - 1,ccl; (* dec and test bit counter *) ram p -> @BIT_COUNT_SIOP. au chan_reg := chan_reg + #$F0. (* change to Din channel *) chan tbs := in_m1_c1. If PSL = 0 then goto count_siop; (* test input data bit *) disable_mtsr. au chan_reg := chan_reg + #$10. (* change back to clock chan *) au p := diob + 1; (* msb first *) ram p -> @DATA_SIOP. If flag1 = 1 then goto count_siop,flush. (* shift direction ? *) au diob := diob + max; (* lsb first *) ram diob -> @DATA_SIOP. count_siop: If Z = 0 then goto end_siop,flush. chan neg_lsl, neg_tdl, neg_mrl; (* - if done, IRQ and end *) chan cir; end. (**********************************************************************) (* UNUSED ENTRIES - execute appropriate termination *) (**********************************************************************) %entry name = dud_siop; start_address End_of_link; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = 1,m/tsr = 0,pin = x,flag0 = x. %entry name = dud_siop1; start_address End_of_link; disable_match; cond hsr1 = 0, hsr0 = 1,lsr = x,m/tsr = x,pin = x,flag0 = x. %entry name = dud_siop2; start_address End_of_link; disable_match; cond hsr1 = 1, hsr0 = 0,lsr = x,m/tsr = x,pin = x,flag0 = x.