(**********************************************************************) (* *) (* Function: COMM Brushless motor commutation function *) (* *) (* Creation Date: 08/Jun/92 From: NEW *) (* *) (* Author: Jeff Wright *) (* *) (* Description: *) (* ------------ *) (* This function generates the commutation drive signals required for *) (* a brushless motor. These would typically be externally combined *) (* with a PWM also generated by the TPU on another channel. *) (* The number of commutation states and number of drive pins is *) (* programmable to support a variety of motor types including 3 and 4 *) (* phase brushless d.c. The function has been designed for both *) (* sensored and sensorless commutation. *) (* In the sensorless mode the commutation switching is based on the *) (* value of an angular position counter created by another TPU func. *) (* on another channel such as FQD or DUC. The function basically takes*) (* the form of a state machine: on a periodic basis,or on receipt of a*) (* link, the remote position count is compared against the boundaries *) (* of the current state and if it is outside then the state number is *) (* updated and the channel pins driven to the new state using a match *) (* The length of each commutation state in position counts is prog'd *) (* by the user over an 8 bit range. *) (* In sensored mode a link from sensor decode funciton running on *) (* another channel forces the current state to be output on the pins. *) (* HSRs allow the host CPU to force any state during initialisation. *) (* *) (* Updates: By: Modification: *) (* -------- --- ------------- *) (* 02/9/92 JW Now use next update match to set pins - this allow*) (* simultaneous changing of multiple channel pins. *) (* 21/10/92 JW Changed state flow to provide new 'link force' *) (* mode to support hall effect decode function. *) (* 16/Jun/93 JW Changed revNo from alpha to 1.0 - first release *) (* 12/Aug/93 JL Converted to new TPUMASM syntax. *) (* 19/Jul/94 JL Fix problem in match mode state number roll-over *) (* or roll-under. *) (* 07/Sep/94 RS Changed preload from p to diob in HSR %11. This *) (* fault caused other, non-COMM channels to be forced*) (* to outputs, and a random state number to be *) (* selected. *) (* Inverted test in conditional branch in state S3 *) (* to make output pin level have same value as that *) (* defined in parameter RAM. *) (* *) (*--------------------------------------------------------------------*) (* Standard Exits Used:- End_Of_Phase: N End_Of_Link: N *) (* *) (* External Files included: NONE *) (* *) (* CODE SIZE excluding standard exits = 50 LONG WORDS *) (*--------------------------------------------------------------------*) (* *) (* *) (********** This Revision: 1.2 *********) (* *) (********** LAST MODIFIED: 07/Sep/94 BY: Richard Soja *********) (* *) (**********************************************************************) (***************************************************************************) (*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. 1994 *) (***************************************************************************) (*()()()()()()()()()()() DATA STRUCTURE ()()()()()()()()()()()()()()()*) (* *) (* name: Written By: Location Bits: *) (* ----- ----------- --------------- *) (* COUNT_PTR CPU Parameter0 0..7 *) (* Address in PRAM of position counter used for *) (* State tests. *) (* *) (* NO_OF_PINS CPU Parameter0 8..15 *) (* Number of channels to be used for commutation *) (* *) (* STATE_NO BOTH Parameter1 0..7 *) (* Contains the current state number - init by CPU*) (* *) (* NO_OF_STATES CPU Parameter1 8..15 *) (* The number of states in commutation sequence *) (* *) (* OFFSET CPU Parameter2 0..15 *) (* CPU supplied angle to vary switching points *) (* *) (* UPDATE_RATE CPU Parameter3 0..15 *) (* Defines freq of update of comm signals in match*) (* mode. *) (* *) (* UPPER BOTH Parameter4 0..15 *) (* Contains upper boundary of current state. *) (* *) (* LOWER BOTH Parameter5 0..15 *) (* Contains lower boundary of current state. *) (* *) (* STATE_0 .. STATE_N CPU Parameter0..n 0..15 *) (* Table in 1st slave channel PRAM - contains *) (* the length and pinstates of each commutation *) (* state. State length:upper byte, pins:lower byte*) (* *) (* HSQ1 HSQ0 Action *) (* ---- ---- ------ *) (* 0 x Match mode. *) (* 1 0 Link mode - with state tests. *) (* 1 1 Link mode - force current state. *) (* *) (* hsr1 hsr0 Action *) (* ---- ---- ------ *) (* 0 0 No action *) (* 0 1 No Action. *) (* 1 0 Force current state. *) (* 1 1 Update commutation - immediate match ref. *) (* *) (* Links Accepted: YES Links Generated: NO *) (* *) (* Interrupts Generated After: Init and commutation (master chan) *) (* *) (*()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()*) (*+++++++++++++++++++++ PARAMETER MACROS +++++++++++++++++++++++++++*) %macro COUNT_PTR_COMM 'prm0'. %macro NO_OF_PINS_COMM 'prm0'. %macro STATE_NO_COMM 'prm1'. %macro NO_OF_STATES_COMM 'prm1'. %macro OFFSET_COMM 'prm2'. %macro UPDATE_RATE_COMM 'prm3'. %macro UPPER_COMM 'prm4'. %macro LOWER_COMM 'prm5'. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*) (*====================================================================*) (*||||||||||||||||||||| MICROCODE STARTS BELOW |||||||||||||||||||||*) (*VVVVVVVVVVVVVVVVVVVVV--------------------------VVVVVVVVVVVVVVVVVVVVV*) (**********************************************************************) (* *) (* ENTRY name: FORCE_COMM *) (* *) (* STATE(S) ENTERED: S1 *) (* *) (* PRELOAD PARAMETER : COUNT_PTR_COMM *) (* *) (* ENTER WHEN : HSR = %10 or a link in link force mode. *) (* *) (* ACTION: configures pins according to current state number. *) (* disables match servicing to allow host to force states in *) (* both link and match modes. Uses a match to setup pins. *) (* *) (**********************************************************************) %entry name = force_comm; start_address *; disable_match; cond hsr1 = 1, hsr0 = 0,lsr = x,m/tsr = x,pin = x,flag0 = x; ram p <- @COUNT_PTR_COMM. %entry name = force_comm1; start_address *; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = 1,m/tsr = 0,pin = x,flag0 = 0; ram p <- @COUNT_PTR_COMM. force_comm: au dec := p_high; ram p <- @NO_OF_STATES_COMM. If true then goto tst_link_comm. (**********************************************************************) (* *) (* ENTRY name: UPDATE_COMM *) (* *) (* STATE(S) ENTERED: S2 *) (* *) (* PRELOAD PARAMETER : COUNT_PTR_COMM *) (* *) (* ENTER WHEN : HSR = %11 or a link in link update mode. *) (* *) (* ACTION: Perform state tests. If match mode then schedule update *) (* match and enable match servicing. If link mode then schedul*) (* match to update pins but disable match servicing. *) (* *) (**********************************************************************) %entry name = update_comm; start_address *; disable_match; cond hsr1 = 1, hsr0 = 1,lsr = x,m/tsr = x,pin = x,flag0 = x; ram diob <- @COUNT_PTR_COMM. %entry name = link_comm; start_address *; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = 1,m/tsr = 0,pin = x,flag0 = 1; ram diob <- @COUNT_PTR_COMM. Update_comm: au ert := tcr1. (**********************************************************************) (* *) (* ENTRY name: MATCH_COMM *) (* *) (* STATE(S) ENTERED: S3 *) (* *) (* PRELOAD PARAMETER : COUNT_PTR_COMM *) (* *) (* ENTER WHEN : HSR = %00, mtsr = 1 lsr = x *) (* *) (* ACTION: Must be in match mode - Perform state tests. schedule next *) (* match to update pins - enable match servicing. *) (* *) (**********************************************************************) %entry name = match_comm; start_address *; disable_match; cond hsr1 = 0, hsr0 = 0,lsr = x,m/tsr = 1,pin = x,flag0 = x; ram diob <- @COUNT_PTR_COMM. match_comm: au p := diob; ram diob <- by_diob. (* fetch position counter from another func*) au dec := p_high; (* load up dec with NO_OF_PINS *) ram p <- @OFFSET_COMM. au sr := p + diob; (* add CPU supplied angular offset *) ram diob <- @LOWER_COMM. tst_lower_lim_comm: au sr := sr - diob,ccl; (* [count+offset] - lower *) ram p <- @UPPER_COMM. (* normalise around lower to ease tests*) If N = 0 then goto tst_upper_lim_comm. (* count < lower? *) au a := p - diob; (* upper - lower *) ram p <- @STATE_NO_COMM. (* get current state & NO_OF_STATES *) au p_low := p_low - 1,ccl; (* move down a state *) ram p -> @STATE_NO_COMM. If N = 0 then goto new_limits_comm,flush. au p_low := p_high - 1; ram p -> @STATE_NO_COMM. (* reset state counter if underflow*) new_limits_comm: call get_state_comm,flush. (* get new state length *) goto tst_mode_comm; ram diob -> @UPPER_COMM. (* new UPPER = old LOWER *) au diob := diob - a; (* new LOWER = old LOWER - state length*) ram diob -> @LOWER_COMM. tst_upper_lim_comm: au nil := sr - a,ccl. (* [count+offset-lower]-[upper-lower] *) If less_than = true then goto tst_mode_comm,flush. (* in range?*) au a := p_low + 1. (* move up a state *) au p_low := p_high - a,ccl; ram p -> @STATE_NO_COMM. If Z = 1 then goto new_lim_comm,flush. (* reset if overflow *) au p_low := a; ram p -> @STATE_NO_COMM. new_lim_comm: call get_state_comm,flush. (* get new state length *) ram diob <- @UPPER_COMM. ram diob -> @LOWER_COMM. (* new LOWER = old UPPER *) au diob := diob + a; ram diob -> @UPPER_COMM. (* new UPPER = old UPPER + state length*) tst_mode_comm: If hsq1 = 0 then goto get_pins_comm,flush; (*match or link mode?*) enable_mtsr. (* enable match services on master chan*) tst_link_comm: If hsq0 = 0 then goto get_pins_comm,flush; (* which link mode? *) disable_mtsr; (* disable match services in link and host force modes*) chan set flag0. chan clear flag0. get_pins_comm: call get_state_comm; (* get state pin sequence *) ram diob <- @UPDATE_RATE_COMM. au sr := ert + diob; (* calculate next match time *) ram p <- @STATE_NO_COMM. (* JL 19/JUL/94 *) (* commutation state number *) (* must be in p before calling*) (* get_state_comm *) commutate_comm: au p :=>> p,ccl. (* get next pin value *) If C = 1 then goto tst_count_comm; chan tbs:= out_m1_c1, PAC := high. au dec := dec - 1,ccl. (* decrement pin counter *) chan tbs:= out_m1_c1, PAC := low. tst_count_comm: au ert := sr; (* schedule match to chan set pins*) chan write_mer, neg_mrl, neg_tdl. If Z = 0 then goto commutate_comm. (* more channels to do ? *) au chan_reg := chan_reg + #$10. (* move to next channel *) chan neg_lsl; (* end here *) chan cir; end. (*------------------------ Subroutine GET_STATE ----------------------------*) (* enter with p = state number, exit with p = state parameter *) get_state_comm: au diob :=<< p_low + #$08. (* form address of state parameter*) au diob := chan_reg + diob. return; ram p <- by_diob. (* get state length and pinstates of new state*) au a := p_high; ram diob <- @LOWER_COMM. (*--------------------------------------------------------------------------*) (**********************************************************************) (* UNUSED ENTRIES - execute appropriate termination *) (**********************************************************************) %entry name = dud_comm1; start_address End_of_phase; disable_match; cond hsr1 = 0, hsr0 = 1.