(**********************************************************************) (* *) (* Function: QDEC - QUADRATURE DECODE *) (* *) (* Creation Date: 10/Dec/91 From: NEW *) (* *) (* Author: Jeff Wright *) (* *) (* Description: *) (* ------------ *) (* This function uses 2 channels (each must be programmed as QDEC to *) (* decode a pair of out of phase signals and produce a resulting 16 *) (* bit bidirectional position counter for the CPU. *) (* This function is a completly new and is not derived from the QD *) (* function that is on 332 silicon up to rev_P. Principally the same, *) (* QDEC has better noise immunity and better initialisation. *) (* *) (* NOTE: *) (* Could change End_of_link to End_of_phase to allow QDEc to replace *) (* QD in the original TPU standard function chan set. *) (* *) (* Updates: By: Modification: *) (* -------- --- ------------- *) (* 9/Jul/92 JW REV B: Added time stamp to write the captured *) (* quadrature edge time into PRAM. This is useful for*) (* interpolation during very slow count rates. *) (* - added new hsr state just to read tcr1. *) (* Initialisation also reads tcr1. Code size up by 2.*) (* 11/Apr/93 JL Convert to new syntax and changed rev. to 1.0. *) (* *) (*--------------------------------------------------------------------*) (* Standard Exits Used:- End_Of_Phase: N End_Of_Link: Y *) (* *) (* External Files Included: NONE. *) (* *) (* CODE SIZE excluding standard exits = 29 LONG WORDS *) (*--------------------------------------------------------------------*) (* *) (********** This Revision: 1.0 *********) (* *) (********** 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(x..y): *) (* ----- ----------- --------------------- *) (* EDGE_TIME_QD TPU Parameter0 0..15 *) (* Updated to hold captured tcr1 time of latest *) (* edge. ONE CHANNEL ONLY!!! *) (* *) (* POSITION_CNT_QD CPU/TPU parameter1 0..15 *) (* 16 bit counter that is the output of this func.*) (* Can be written or read at any time by CPU *) (* ONE CHANNEL ONLY!!!! *) (* *) (* CHAN_PINSTATE_QD CPU/TPU Parameter3 0..15 *) (* Used to store the level of the pin for use in *) (* noise reject and lead/lag tests. Two values :- *) (* $8000 represents high pin, $0000 low pin. *) (* Can be init'ed by CPU to force first accepted *) (* edge type. *) (* *) (* CORR_PIN_PTR_QD CPU Parameter4 0..7 *) (* Address of the CHAN_PINSTATE parameter of the *) (* other QD channel. *) (* *) (* EDGE_TIM_PTR_QD CPU Parameter5 0..7 *) (* Address of the EDGE_TIME_QD parameter.- must *) (* point to lsb [i.e. odd address] of EDGE_TIME_QD*) (* *) (* TCR1_VAL_QD TPU Parameter2 0..15 *) (* Updated by TPU to contain the latest TCR1 value*) (* in response to a read tcr1 HSR. *) (* *) (* hsr1 hsr0 Action *) (* ---- ---- ------ *) (* 0 X No action *) (* 1 0 Read TCR1. *) (* 1 1 Initialise function. *) (* *) (* *) (* HSQ1 HSQ0 Action *) (* ---- ---- ------ *) (* X 0 Primary channel *) (* X 1 Secondary channel *) (* *) (* Links Accepted: no Links Generated: NO *) (* *) (* Interrupts Generated After: none *) (* *) (*()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()*) (*+++++++++++++++++++++ PARAMETER MACROS +++++++++++++++++++++++++++*) (* EDGE_TIME prm0 *) (* POSITION_CNT prm1 *) %macro TCR1_VAL_QDEC 'prm2'. %macro CHAN_PINSTATE_QD 'prm3'. %macro CORR_PIN_PTR_QD 'prm4'. %macro EDGE_TIM_PTR_QD 'prm5'. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*) (*====================================================================*) (*||||||||||||||||||||| MICROCODE STARTS BELOW |||||||||||||||||||||*) (*VVVVVVVVVVVVVVVVVVVVV--------------------------VVVVVVVVVVVVVVVVVVVVV*) (**********************************************************************) (* *) (* ENTRY name: AUTO_INIT_QDEC *) (* *) (* STATE(S) ENTERED: S1 *) (* *) (* PRELOAD PARAMETER : NONE *) (* *) (* ENTER WHEN : HSR = %11 *) (* *) (* ACTION: Init., make pin input & detect either edge. setup init *) (* value of CHAN_PINSTATE. *) (* *) (**********************************************************************) %entry start_address *; disable_match; name = AUTO_INIT_QDEC; cond hsr1 = 1, hsr0 = 1. auto_init_qdec: chan pac := any_trans, tbs := in_m1_c1, enable_mtsr. au chan_reg := chan_reg; (* latch latest pinstate *) neg_tdl, neg_mrl, neg_lsl. (* - and any future edges *) au p := max; ram p -> @CHAN_PINSTATE_QD. (* initialise PINSTATE param *) If PSL = 1 then goto read_tcr1_qdec,flush. au p := 0; ram p -> @CHAN_PINSTATE_QD. (**********************************************************************) (* *) (* ENTRY name: READ_TCR1_QDEC *) (* *) (* STATE(S) ENTERED: S3 *) (* *) (* PRELOAD PARAMETER : NONE *) (* *) (* ENTER WHEN : HSR = %10 *) (* *) (* ACTION: Read TCR1 and store value in TCR1_VAL. *) (* *) (**********************************************************************) %entry start_address *; disable_match; name = READ_TCR1_QDEC; cond hsr1 = 1, hsr0 = 0. read_tcr1_qdec: au diob := tcr1; (* read and store current value of tcr1*) ram diob -> @TCR1_VAL_QDEC; end. (**********************************************************************) (* *) (* ENTRY name: EDGE_QDEC *) (* *) (* STATE(S) ENTERED: S2 *) (* *) (* PRELOAD PARAMETER : CHAN_PINSTATE_QD *) (* *) (* ENTER WHEN : m/tsr = 1 *) (* *) (* ACTION: Latch pinstate, if equal to last then quit (noise) else *) (* update PINSTATE and perform lead/lag tests. From results, *) (* inc or dec POSITION_CNT.Update EDGE_TIME. *) (* *) (**********************************************************************) %entry ram p <- @CHAN_PINSTATE_QD; start_address *; disable_match; name = EDGE_QDEC; cond hsr1 = 0, hsr0 = 0,m/tsr = 1,lsr = 0. edge_qdec: au chan_reg := chan_reg; (* latch latest pinstate and *) neg_tdl, neg_mrl. (* - dont lose any future edges *) au sr := p,ccl; (* put last pinstate into Nbit *) ram diob <- @CORR_PIN_PTR_QD. If PSL = 0 then goto tst_lo_qdec. au p := p + max; (* flip CHAN_PINSTATE $0000 <-> $8000*) ram diob <- by_diob. (* get CHAN_PINSTATE of other QDEC chan*) au nil := sr + max;ccl. (* flip N bit to allow single test *) tst_lo_qdec: If N = 0 then goto End_of_link, flush. (* new = old pinstate=> end*) au sr := p + diob,ccl; (* add the CHAN_PINSTATEs of both chans*) ram p -> @CHAN_PINSTATE_QD. (* store new pinstate of this chan*) au p := ert; ram diob <- @EDGE_TIM_PTR_QD. (* get edge time and storage pointer*) If hsq0 = 0 then goto tst_n_qdec. (* primary or secondary? *) au diob := diob + 1; (* inc pointer to point at position counter*) ram p -> by_diob. (* store quadrature edge time *) au nil := sr + max;ccl. (* flip N bit if sec chan - for 1 test*) tst_n_qdec: If N = 0 then goto dec_cnt_qdec. (* lead/lag test *) inc_cnt_qdec: ram p <- by_diob. au p := p + 1; (* get count, inc it and store it in #2 *) ram p -> by_diob; (* cycles for coherency *) end. dec_cnt_qdec: au p := p - 1; (* get count, dec it and store coherently*) ram p -> by_diob; end. (**********************************************************************) (* UNUSED ENTRIES - execute appropriate termination *) (**********************************************************************) %entry start_address End_of_link; name = del_lnk_qdec; cond hsr1 = 0,hsr0 = 1. %entry start_address End_of_link; name = del_lnk_qdec1; cond hsr1 = 0,hsr0 = 0,lsr = 1.