(**********************************************************************) (* *) (* Function: FQM - FREQUENCY MEASUREMENT *) (* *) (* Creation Date: 27/Jul/92 From: NEW *) (* *) (* Author: Kevin Anderson *) (* *) (* Description: *) (* ------------ *) (* Counts the number of pulses presented to a channel pin within a *) (* a CPU specified time window. The pulse count is presented to the *) (* CPU in the form of a 16 bit number. The user may select between *) (* starting pulse accumulation on a rising or falling edge. The time *) (* base is selectable between tcr1 and tcr2. There are two major *) (* modes of operation - single shot and continuous. *) (* *) (* In single shot mode the function counts the number of input pulses *) (* in one sample window, interrupts the CPU, and stops. The start *) (* of the sample window is aligned with the start edge of the first *) (* pulse after initialization. *) (* *) (* In continuous mode the function counts the number of pulses in a *) (* sample window repetatively, interrupting the CPU after each sample *) (* window is completed. The start of the first sample window after *) (* initialization is aligned with the start edge of the first pulse. *) (* No pulses are lost between sample windows in continuous mode. *) (* *) (* In either mode, the pulse count from the previous window is not *) (* overwritten until the current sample window is complete. This *) (* allows the CPU time to respond to the interrupt and read the last *) (* accumulated pulse count. The CPU may restart the accumulation at *) (* any time, in which case the partial accumulation is discarded. *) (* *) (* This function is optimized for small code size and fast execution *) (* It does not attempt to filter out any noise on the input. If the *) (* input signal is susceptible to noise a companion function PAPW *) (* (Pulse Accumulate in a Programmable Window) may offer some *) (* improved performance at the expense of increased code size. *) (* Please see the PAPW programming note for details. *) (* *) (* Updates: By: Modification: *) (* -------- --- ------------- *) (* 16/Jun/93 JW Changed revNo from A to 1.0 - first release. *) (* 12/Aug/93 JL converted to new TPUMASM syntax and removed *) (* preloads of none in used entries. *) (* *) (*--------------------------------------------------------------------*) (* Standard Exits Used:- End_Of_Phase: Y End_Of_Link: Y *) (* *) (* External Files included: NONE *) (* *) (* CODE SIZE excluding standard exits = 20 LONG WORDS *) (*--------------------------------------------------------------------*) (* *) (* *) (********** This Revision: 1.1 *********) (* *) (********** LAST MODIFIED: 12/Aug/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: *) (* ----- ----------- --------------- *) (* CH_CONTROL_FQM CPU Parameter2 0..8 *) (* Standard channel configuration parameter. *) (* *) (* WINDOW_FQM CPU Parameter3 0..15 *) (* Sample window size in TCR counts. $8000 max. *) (* *) (* COUNT_FQM TPU Parameter4 0..15 *) (* Result register. Number of complete pulses in *) (* previous window. *) (* *) (* ACCUM_FQM TPU Parameter5 0..15 *) (* Storage for in-progress accumulation *) (* *) (* hsr1 hsr0 Action *) (* ---- ---- ------ *) (* 0 0 No service *) (* 1 0 Initialize *) (* *) (* HSQ1 HSQ0 Action *) (* ---- ---- ------ *) (* 0 0 Falling edge - Single shot mode *) (* 0 1 Falling edge - Continuous mode *) (* 1 0 Rising edge - Single shot mode *) (* 1 1 Rising edge - Continuous mode *) (* *) (* Links Accepted: NO Links Generated: NO (except for test) *) (* *) (* Interrupts Generated After: End of every window. *) (* *) (*()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()*) (*+++++++++++++++++++++ PARAMETER MACROS +++++++++++++++++++++++++++*) %macro CH_CONTROL_FQM 'prm2'. %macro WINDOW_FQM 'prm3'. %macro COUNT_FQM 'prm4'. %macro ACCUM_FQM 'prm5'. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*) (*====================================================================*) (*||||||||||||||||||||| MICROCODE STARTS BELOW |||||||||||||||||||||*) (*VVVVVVVVVVVVVVVVVVVVV--------------------------VVVVVVVVVVVVVVVVVVVVV*) (**********************************************************************) (* *) (* ENTRY name: INIT_FQM *) (* *) (* STATE(S) ENTERED: S1 *) (* *) (* PRELOAD PARAMETER : CH_CONTROL_FQM *) (* *) (* ENTER WHEN : HSR = %10 m/tsr = X lsr = X FLAG = X pin = X *) (* *) (* ACTION : Configure channel, set CFLAG0 to indicate that the next *) (* transistion will be the first one since initialization, *) (* clear all latches and enable service requests. *) (* *) (**********************************************************************) %entry name = INIT_FQM; start_address *; disable_match; cond hsr1 = 1,hsr0 = 0,lsr=x,m/tsr=x,pin=x,flag0=x; ram p <- @CH_CONTROL_FQM. INIT_FQM: chan config:= p, (* initialize the channel *) enable_mtsr; (* make sure service requests are enabled *) chan set flag0. (* next edge is 1st after init *) chan neg_tdl,neg_lsl. (* clear transition and link latches *) END_S2_FQM: chan neg_mrl; (* clear match latch *) end. (* end of S1 *) (**********************************************************************) (* *) (* ENTRY name: COUNT_EM_FQM *) (* *) (* STATE(S) ENTERED: S3 *) (* *) (* PRELOAD PARAMETER : ACCUM_FQM *) (* *) (* ENTER WHEN : HSR = %00 m/tsr = 1 lsr = X FLAG = 0 pin = X *) (* *) (* ACTION : All other events except the 1st edge after initializa- *) (* tion enter here. Since tdl blocks mrl, the order of *) (* servicing is important. On entry, mrl is checked for *) (* assertion (end of window time). If it is asserted it *) (* happened before any pending transition. Thus the value *) (* in ACCUM_FQM is the actual number of pulses in the just *) (* expired period. This value is then copied to COUNT_FQM *) (* and ACCUM_FQM is cleared and a CPU interrupt generated. *) (* If the single shot mode is active the channel is put in *) (* an idle state. *) (* *) (* However, if the continuous mode is active, the next *) (* match event is scheduled and mrl is cleared. Then tdl *) (* is checked for assertion and if it is, ACCUM_FQM is *) (* incremented and its latch is cleared. In the case of a *) (* new window, this would be the 1st pulse count of the *) (* window. *) (* *) (* If, upon entry, mrl is not asserted, only tdl servicing *) (* is required and the state is exited without clearing the *) (* mrl. *) (* *) (**********************************************************************) %entry name = COUNT_EM_FQM; start_address *; disable_match; cond hsr1 = 0,hsr0 = 0,lsr=x,m/tsr=1,pin=x,flag0=0; ram p <- @ACCUM_FQM. COUNT_EM_FQM: if mrl=0 then goto TDL_FQM, flush. (* no match - service tdl *) ram p->@COUNT_FQM. (* store new pulse count for CPU read *) au read_mer, (* get match time for next window update *) p:=0; (* clear accumulated value *) ram diob<-@WINDOW_FQM. (* get window width *) au ert:=ert + diob; (* calculate next end of window time *) chan write_mer, (* and write it to the match register *) neg_mrl; (* clear the match latch *) chan cir. (* schedule a CPU interrupt *) if hsq0=0 then goto END_S3_FQM, flush; (* single shot can exit *) chan disable_mtsr. (* always disable - save 1 instruction *) TDL_FQM: if tdl=0 then goto END_S3_FQM, flush; (* no update if no tdl *) chan enable_mtsr. (* re-enable if continuous mode *) au p:= p + 1; (* add this transition to @ACCUM_FQM *) chan neg_tdl. (* clear the tdl latch *) (* next microinstruction is for test only *) (* au link:='30'h. generate the link for channel 3 *) END_S3_FQM: ram p->@ACCUM_FQM; (* store either 0 or ACCUM_FQM + 1 *) end. (* end of state 3 *) (**********************************************************************) (* *) (* ENTRY name: FIRST_EDGE_FQM *) (* *) (* STATE(S) ENTERED: S2 *) (* *) (* PRELOAD PARAMETER : WINDOW_FQM *) (* *) (* ENTER WHEN : HSR = %00 m/tsr = 1 lsr = X FLAG = 1 pin = X *) (* *) (* ACTION : This is the start of a window so add the window time to *) (* the event time and store it in the match register, clear *) (* the pulse counter accumulator, and clear the latches. *) (* Also, clear flag0 to indicate that the next edge is not *) (* the first edge after an initialization. *) (* *) (**********************************************************************) %entry name = FIRST_EDGE_FQM; start_address *; disable_match; cond hsr1 = 0,hsr0 = 0,lsr=x,m/tsr=1,pin=x,flag0=1; ram p <- @WINDOW_FQM. FIRST_EDGE_FQM: if mrl=1 then goto END_S2_FQM, flush. (* unexpected match - exit *) (* next microinstructions are for test only *) (* au diob:=ert; *) (* ram diob->(1,1). *) (* au link:='10'h. generate the link for channel 1 *) (* au link:='30'h. generate the link for channel 3 *) (* end of test code *) au diob:= 0; (* clear the in-window accumulator *) ram diob->@ACCUM_FQM. chan clear flag0; (* next edge is NOT 1st after INIT *) au ert:= ert + p; (* load the match register with the *) chan write_mer, (* end of window time *) neg_tdl,neg_mrl; (* clear latches *) end. (* end of s2 *) (**********************************************************************) (* UNUSED ENTRIES - execute appropriate termination *) (**********************************************************************) %entry name = UNUSED_FQM; start_address END_OF_LINK; disable_match; cond hsr1=0,hsr0=1,lsr=x,m/tsr=x,pin=x,flag0=x. %entry name = UNUSED_FQM; start_address END_OF_LINK; disable_match; cond hsr1=1,hsr0=1,lsr=x,m/tsr=x,pin=x,flag0=x. %entry name = UNUSED_FQM; start_address END_OF_LINK; disable_match; cond hsr1=0,hsr0=0,lsr=1,m/tsr=0,pin=x,flag0=x.