*Source Code ************************************************************************** * PROGRAM: FINAL.ASM * PROGRAMMER: MICAH O'HALLORAN AND STEVE HOROWITZ * DATE: DEC. 2, 1998 * VERSION: 1.5 * DESCRIPTION: THIS PROGRAM OUTPUTS A PWM SIGNAL APPROPRIATE FOR DRIVING * STANDARD SERVOS. THE PERIOD FOR THE TOTAL WAVE IS * ABOUT 21ms, AND THE PWM VARIES BETWEEN ABOUT 1.05ms (LOW) * TO ABOUT 1.9ms (HIGH). NOTE THAT THE TIMING OF THIS PROGRAM * DEPENDS ON THE SETTINGS OF PR0 AND PR1 IN THE TMSK2 REGISTER. * IT ALSO CONTAINS THE ROUTINE FOR THE TAKEOVER INPUT CAPTURE. * IT IMPLEMENTS THE LANDING BEHAVIOR, TAKEOVER BEHAVIOR, AND * BALANCING BEHAVIOR. * USES: OC2, OC3, OC4, 0C5, IC1 ************************************************************************** * * DATA SECTION * ************************************************************************** * INTERRUPT VECTORS ORG $FFFE FDB MAIN ORG $FFE0 FDB OC5_ISR FDB OC4_ISR FDB OC3_ISR FDB OC2_ISR ORG $FFEE FDB IC1_ISR *************************************************************************** * CONSTANTS *************************************************************************** * TCTL1 EQU $1020 TCNT EQU $100E TFLG1 EQU $1023 TMSK1 EQU $1022 TMSK2 EQU $1024 CFORC EQU $100B TOC1 EQU $1016 TOC2 EQU $1018 TOC3 EQU $101A TOC4 EQU $101C TOC5 EQU $101E TCTL2 EQU $1021 TIC1 EQU $1010 TIC2 EQU $1012 TIC3 EQU $1014 PORTB EQU $1004 OPTION EQU $1039 ADCTL EQU $1030 ADR1 EQU $1031 ADR2 EQU $1032 ADR3 EQU $1033 ADR4 EQU $1034 DDRC EQU $1007 PORTC EQU $1003 PORTE EQU $100A PACTL EQU $1026 ****FOR SERVOS***** PULS_LEN EQU 42000 ;THE LENGTH OF ONE PERIOD OF SIGNAL MID_POSITION EQU 3000 ;MIDDLE POSITION (IN E-CLOCKS) OF SERVOS OC2_START_DELAY EQU 1000 ;THE E-CLOCK DELAY BEFORE OC2 SHOULD START ****FOR TAKEOVER SYSTEM**** MICRO_ON EQU %11111110 ;BITMAPS FOR SETTING PORT B RCVR_ON EQU %00000001 ; PULLED_LEFT EQU 2500 ;THE THRESHOLD VALUE FOR STICK TO COUNT AS "LEFT" PULLED_RIGHT EQU 3400 ;" " " " " " " " "RIGHT" ****FOR SAMPLING ROUTINE**** ROLL_ON EQU %11111101 ;THE MASK FOR TURNING ROLL MEASUREMENT ON PITCH_ON EQU %00000010 ;THE MASK FOR TURNING PITCH MEASUREMENT ON OC5_DELAY EQU 4000 ;DELAY FROM START OF OC4 BEFORE OC5 RUNS QUEUE_LENGTH EQU 4 ;LENGTH OF PITCH AND ROLL QUEUES ****FOR BALANCING BEHAVIOR**** MID_LEV_ROLL EQU %01100111 ;MID LEVELS FOR TILT AND PITCH MID_LEV_PITCH EQU %01101111 ; ****FOR LANDING BEHAVIOR**** *BAT_THRESH EQU %10011001 ;LANDING TAKEOVER THRESHOLD VALUE (3V) BAT_THRESH EQU %00011001 *************************************************************************** * END OF CONSTANTS *************************************************************************** *************************************************************************** * VARIABLES *************************************************************************** * ORG $0042 ;STORE ALL VARIABLES IN THIS SECTION ****GLOBAL VARIABLES**** TEMP_VAR RMB 2 ;MAKE A TEMPORARY VARIABLE FOR ALL'S USE ****FOR SERVOS****** SERV1_UP RMB 2 ;THE 'UPTIMES' OF THE PWM FOR SERVOS OC2_TIM_LO RMB 2 ;THE LENGTH OF LOW TIME TO COMPLETE A CYCLE SERV2_UP RMB 2 ; OC3_TIM_LO RMB 2 ; SERV3_UP RMB 2 ; OC4_TIM_LO RMB 2 ; ****FOR TAKEOVER SYSTEM***** IC1_START RMB 2 ;KEEPS THE FIRST EDGE OF IC1 SUBSUM_TAK RMB 1 ;KEEPS TRACK OF SUBSUMPTION OF TAKEOVER SYSTEM ****FOR SAMPLING ROUTINE**** CUR_ROLL RMB 2 CUR_PITCH RMB 2 PITCHQ RMB QUEUE_LENGTH PITCH_AVG RMB 1 ROLLQ RMB QUEUE_LENGTH ROLL_AVG RMB 1 ****FOR LANDING ROUTINE**** ARM_LAND RMB 1 ;0 =NOT YET ARMED, 1 = ARMED SUBSUM_LAND RMB 1 ;ALLOWS LANDING TO SUBSUME ITSELF (WHEN DONE) BAT_MEAS RMB 1 ;HOLDS LATEST BATTERY MEASUREMENT ****FOR BALANCING ROUTINE******** SUBSUM_BAL RMB 1 ;ALLOWS PROCESSES TO SUBSUME BALANCING *************************************************************************** * END OF VARIABLES *************************************************************************** ORG $F800 ************************************************************************** * MAIN PROGRAM ************************************************************************** * MAIN LDS #$0041 LDD #MID_POSITION ;INITIALIZE ALL 3 SERVOS TO MID_POSITION STD SERV1_UP STD SERV2_UP STD SERV3_UP LDAA TMSK2 ;SET TIMER PRESCALAR TO FASTEST SETTING ANDA #%11111100 ; STAA TMSK2 ; LDAA #%00000000 ;INITIALIZE PORT C'S VALUE STAA PORTC ; LDAA #%11111111 ;SET PORTC TO ALL OUTPUTS STAA DDRC ; LDAA PORTB ;SET THE CONTROL TO INITIALLY BELONG TO THE ANDA #MICRO_ON ;MICROPROCESSOR STAA PORTB ;(DON'T ALTER OTHER BITS) LDAA PORTB ;SET TO READ THE ROLL AXIS FIRST ANDA #ROLL_ON ;ON DATA MEASUREMENTS STAA PORTB ; LDAA OPTION ;TURN ON A/D CONVERTER ORAA #%10000000 ; STAA OPTION ; LDAA $FF ;DELAY FOR THE START OF MAIN_AD_DELAY DECA ;THE A/D ROUTINES BNE MAIN_AD_DELAY LDD #PITCHQ ;GET THE FIRST SLOT IN QUEUE1 STD CUR_PITCH ;AND MAKE A POINTER TO IT LDD #ROLLQ ;GET THE FIRST SLOT IN QUEUE2 STD CUR_ROLL ;AND MAKE A POINTER TO IT LDAA #0 STAA SUBSUM_BAL ;TURN BALANCING ON STAA SUBSUM_TAK ;" TAKEOVER " STAA SUBSUM_LAND ;" LANDING " STAA ARM_LAND ;DISARM STAA BAT_MEAS ;SET BATTERY MEASUREMENT TO 0 JSR INIT_IC1 ;INITIALIZE THE IC1 PROCESS JSR INIT_OCS ;INITIALIZE ALL OUTPUT COMPARES CLI ;TURN ON INTERRUPTS HERE LDAA PORTE ;LOAD PORTE DATA ANDA #%10000000 ;MASK BIT 7 BNE DIS_ROL ;IF !=0, DISPLAY ROLL DATA DIS_PIT LDAA PITCH_AVG ;SHOW BINARY RUNNING TOTAL STAA PORTC ;ON LEDS BRA MAIN_1 ;WAIT ON INTERRUPTS DIS_ROL LDAA ROLL_AVG STAA PORTC MAIN_1 LDAA SUBSUM_BAL ;CHECK FOR SUBSUMPTION OF BALANCE BNE SKIP_1 ;SUBSUME BALANCE IF '1' JSR CHK_BAL ;BALANCE THE BIRD SKIP_1 LDAA SUBSUM_LAND ;CHECK FOR SUBSUMPTION OF LANDING BNE SKIP_2 ;SUBSUME IF '1' MAIN_2 JSR LAND_CHK ;CHECK FOR LANDING NEED SKIP_2 BRA HERE ************************************************************************** * END OF MAIN ************************************************************************** ************************************************************************** * SUBROUTINE-LAND_CHK * * INPUTS: NONE * OUTPUTS: CHANGES SERV1_UP,SERV2_UP * DESTROYS: REGISTERS A AND B AND X * DESCRIPTION: THIS SUBROUTINE TRIGGERS LANDING SIGNAL ************************************************************************** * THIS FIRST SEGMENT LOOKS FOR INITIAL BATTERY APPLICATION, THEN ARMS * THE LANDING MECHANISM LAND_CHK LDAA ARM_LAND ;CHECK IF ARMED BNE SKIP_ARM ;IF NOT 0, WE ARE ALREADY ARMED LDAA BAT_MEAS ;LOAD THE LATEST BATTERY MEASUREMENT STAA PORTC CMPA #BAT_THRESH ;LOOK FOR THE FIRST TIME BATTERY IS APPLIED BHI ARM_NOW ;IF LARGER THAN THRESHOLD, ARM LANDING MECHANISM BRA RET_LAND_CHK ;ELSE RETURN ARM_NOW LDAA #1 ;ARM THE LANDING MECHANISM STAA ARM_LAND ; BRA RET_LAND_CHK ;RETURN * THIS SEGMENT CHECKS TO SEE IF WE HAVE FALLEN BELOW OUR THRESHOLD SKIP_ARM LDAA BAT_MEAS ;GET LATEST MEASUREMENT CMPA #BAT_THRESH ;COMPARE TO THRESHOLD BLS LAND_EDG ;WE FOUND THE DIP TO INITIATE LANDING BRA RET_LAND_CHK ;ELSE, RETURN * INITIATE LANDING PATTERN LAND_EDG LDAA #1 STAA SUBSUM_TAK ;SUBSUME TAKEOVER AND BALANCING STAA SUBSUM_BAL ;ROUTINES LDAA PORTB ;TAKE CONTROL OF TAIL (OVERRIDING ANDA #MICRO_ON ;REMOTE CONTROL, IF NECESSARY) STAA PORTB ; LDD #MID_POSITION STD SERV1_UP LDD #4000 ;PULL TAIL TO ONE EXTREME STD SERV2_UP ; LDAA #$FF LP_1_OUT LDX #$621 ;WAIT FOR ABOUT .2 sec LP_1_IN DEX BNE LP_1_IN DECA BNE LP_1_OUT LDD #2000 ;PULL TO OTHER EXTREME STD SERV2_UP ; LDAA #$FF LP_2_OUT LDX #$621 ;WAIT FOR ABOUT .2 sec LP_2_IN DEX BNE LP_2_IN DECA BNE LP_2_OUT LDD #4000 STD SERV2_UP LDAA #$FF LP_3_OUT LDX #$621 ;WAIT FOR ABOUT .2 sec LP_3_IN DEX BNE LP_3_IN DECA BNE LP_3_OUT LDD #2000 STD SERV2_UP LDAA #$FF LP_4_OUT LDX #$621 ;WAIT FOR ABOUT .2 sec LP_4_IN DEX BNE LP_4_IN DECA BNE LP_4_OUT LDAA #0 STAA SUBSUM_TAK ;END SUBSUMPTION STAA SUBSUM_BAL ; LDAA #1 STAA SUBSUM_LAND ;SUBSUME SELF PERMANANTLY RET_LAND_CHK RTS ;DONE, SO RETURN ************************************************************************** * SUBROUTINE-CHK_BAL * * INPUTS: NONE * OUTPUTS: CHANGES SERV1_UP,SERV2_UP * DESTROYS: REGISTERS A AND B * DESCRIPTION: THIS SUBROUTINE SETS UP CALLS TO BALANCE SUBROUTINE ************************************************************************** * CHK_BAL LDAA ROLL_AVG ;SET UP REGS FOR SUB CALL LDAB #MID_LEV_ROLL ; JSR BALANCE ;CALL BALANCE SUBD #MID_POSITION ;SUBTRACT OFF MID POSITION STD TEMP_VAR ;MAKE A TEMP STORE LDD #0 ;NEGATE THE RESULT SUBD TEMP_VAR ; ADDD #MID_POSITION ; STD SERV1_UP ;SET SERVO LDAA PITCH_AVG ;SET UP REGS FOR SUB CALL LDAB #MID_LEV_PITCH ; JSR BALANCE ;CALL BALANCE STD SERV2_UP ;SET SERVO RTS ************************************************************************** * SUBROUTINE-BALANCE * * INPUTS: TILT READING IN REGISTER A * MID-TILT VALUE IN REGISTER B * OUTPUTS: THE VALUE TO SET THE SERVO AT IN REGISTER D * DESTROYS: REGISTERS A AND B * DESCRIPTION: THIS SUBROUTINE TAKES IN A READING, COMPARES IT TO * THE CENTER READING, AND LINEARLY MAPS THIS ERROR ONTO * THE SERVO RANGE (2000 TO 4000). IT RETURNS THIS VALUE * IN THE D REGISTER. ************************************************************************** * BALANCE SBA ;SUBTRACT THE CENTER VALUE FROM MEASURED BLO BAL_LOW ;IF TILT VALUE < MID LEVEL VALUE TAB CLRA ; BRA BAL_1 ; BAL_LOW TAB LDAA #$FF ;IF RESULT IS NEG, DO OPPOSITE BAL_1 LSLD ;MULTIPLY BY 32 LSLD ; LSLD ; LSLD ; LSLD ; LSLD ADDD #MID_POSITION ;ADD TO SERVO MID_POSITION RTS ;RETURN ************************************************************************** * SUBROUTINE-INIT_OCS * INPUTS: NONE * OUTPUTS: NONE * DESTROYS: NONE * DESCRIPTION: THIS SUROUTINE SETS UP ALL SERVO OC PINS TO BEGIN AT 0V, RISE * ON THE FIRST COMPARE, AND ENABLES ALL OC INTERRUPTS. IT SETS * OC5, WHICH IS USED TO TIME SAMPLING, TO BE DISCONNECTED FROM * THE OUTPUT PIN. ************************************************************************** * INIT_OCS PSHA ;PRESERVE CONTENTS OF REG. A LDAA PACTL ;SET I4/O5 FUNCTION TO O5 ANDA #%11111011 ; STAA PACTL ; LDAA #%10101000 ;CLEAR OC2-4 PINS TO 0V ON FORCE STAA TCTL1 ;DISCONNECT OC5 FROM ITS PIN LDAA #%01110000 ;FORCE COMPARES ON OC2-4 PINS STAA CFORC ; LDD TCNT ;GET CURRENT TIMER VALUE ADDD #OC2_START_DELAY ;ADD A CERTAIN DELAY BEFORE OC2 STD TOC2 ;STARTS ADDD #150 ;ADD DELAY TO START OF OC3 STD TOC3 ADDD #150 ;ADD ANOTHER DELAY TO START OF OC4 STD TOC4 ADDD #OC5_DELAY ;ADD DELAY FOR SAMPLING ROUTINE STD TOC5 ;TO BE IN DEAD PART OF 21ms PERIOD LDAA #%01111000 ;CLEAR ANY PENDING FLAGS STAA TFLG1 ; LDAA #%11111100 ;SET OC2-4 PINS TO 5V ON FIRST STAA TCTL1 ;SUCCESSFUL COMPARE. LDAA TMSK1 ;TURN ON OC2-5 INTERRUPTS, BUT DON'T ORAA #%01111000 ;ALTER OTHER BITS IN TMSK1 STAA TMSK1 ; PULA ;RESTORE CONTENTS OF REG. A RTS ;RETURN ************************************************************************** * ISR - OC2_ISR * DESCRIPTION: HANDLES THE OC2 INTERRUPT REQUESTS ************************************************************************** * OC2_ISR LDAA TFLG1 ;CHECK FOR VALID INTERRUPT ANDA #%01000000 ; BEQ RET_OC2 ;IF NOT VALID, RETURN STAA TFLG1 ;IF VALID, CLEAR OC2F LDAA TCTL1 ;CHECK TO SEE IF OC2 PIN WAS SET ANDA #%01000000 ;OR CLEARED ON THE COMPARE BEQ OC2_CLRD ;IF 0, IT WAS JUST CLEARED TO 0V LDD TOC2 ;ELSE, IT WAS JUST SET STD OC2_TIM_LO ;TEMP SAVE OF TIME ADDD SERV1_UP ;ADD THE UP TIME OF THE PULSE STD TOC2 ;STORE TIME FOR NEXT COMPARE LDAA TCTL1 ;CLEAR ON NEXT COMPARE ANDA #%10111111 ; STAA TCTL1 ; LDD OC2_TIM_LO ;FIND THE END OF THE PERIOD ADDD #PULS_LEN ;AND STORE INTO TIM_LO STD OC2_TIM_LO ; BRA RET_OC2 ;RETURN OC2_CLRD LDD OC2_TIM_LO ;GET PREV. CALC. END OF PERIOD STD TOC2 ;AND PUT INTO COMPARE REGISTER LDAA TCTL1 ;SET ON NEXT COMPARE ORAA #%11000000 ; STAA TCTL1 ; RET_OC2 RTI ************************************************************************** * ISR - OC3_ISR * DESCRIPTION: HANDLES THE OC3 INTERRUPT REQUESTS ************************************************************************** * OC3_ISR LDAA TFLG1 ;CHECK FOR VALID INTERRUPT ANDA #%00100000 ; BEQ RET_OC3 ;IF NOT VALID, RETURN STAA TFLG1 ;IF VALID, CLEAR OC3F LDAA TCTL1 ;CHECK TO SEE IF OC3 PIN WAS SET ANDA #%00010000 ;OR CLEARED ON THE COMPARE BEQ OC3_CLRD ;IF 0, IT WAS JUST CLEARED TO 0V LDD TOC3 ;ELSE, IT WAS JUST SET STD OC3_TIM_LO ;TEMP SAVE OF TIME ADDD SERV2_UP ;ADD THE UP TIME OF THE PULSE STD TOC3 ;STORE TIME FOR NEXT COMPARE LDAA TCTL1 ;CLEAR ON NEXT COMPARE ANDA #%11101111 ; STAA TCTL1 ; LDD OC3_TIM_LO ;FIND THE END OF THE PERIOD ADDD #PULS_LEN ;AND STORE INTO TIM_LO STD OC3_TIM_LO ; BRA RET_OC3 ;RETURN OC3_CLRD LDD OC3_TIM_LO ;GET PREV. CALC. END OF PERIOD STD TOC3 ;AND PUT INTO COMPARE REGISTER LDAA TCTL1 ;SET ON NEXT COMPARE ORAA #%00110000 ; STAA TCTL1 ; RET_OC3 RTI ************************************************************************** * ISR - OC4_ISR * DESCRIPTION: HANDLES THE OC4 INTERRUPT REQUESTS ************************************************************************** * OC4_ISR LDAA TFLG1 ;CHECK FOR VALID INTERRUPT ANDA #%00010000 ; BEQ RET_OC4 ;IF NOT VALID, RETURN STAA TFLG1 ;IF VALID, CLEAR OC4F LDAA TCTL1 ;CHECK TO SEE IF OC4 PIN WAS SET ANDA #%00000100 ;OR CLEARED ON THE COMPARE BEQ OC4_CLRD ;IF 0, IT WAS JUST CLEARED TO 0V LDD TOC4 ;ELSE, IT WAS JUST SET STD OC4_TIM_LO ;TEMP SAVE OF TIME ADDD SERV3_UP ;ADD THE UP TIME OF THE PULSE STD TOC4 ;STORE TIME FOR NEXT COMPARE LDAA TCTL1 ;CLEAR ON NEXT COMPARE ANDA #%11111011 ; STAA TCTL1 ; LDD OC4_TIM_LO ;FIND THE END OF THE PERIOD ADDD #PULS_LEN ;AND STORE INTO TIM_LO STD OC4_TIM_LO ; BRA RET_OC4 ;RETURN OC4_CLRD LDD OC4_TIM_LO ;GET PREV. CALC. END OF PERIOD STD TOC4 ;AND PUT INTO COMPARE REGISTER LDAA TCTL1 ;SET ON NEXT COMPARE ORAA #%00001100 ; STAA TCTL1 ; RET_OC4 RTI ************************************************************************** * ISR - OC5_ISR * DESCRIPTION: HANDLES THE OC5 INTERRUPT REQUESTS ************************************************************************** * OC5_ISR LDAA TFLG1 ;CHECK FOR VALID INTERRUPT ANDA #%00001000 ; BNE OC5_BEG ;IF NOT VALID, RETURN FROM ISR JMP RET_OC5 OC5_BEG STAA TFLG1 ;IF VALID, CLEAR OC5F LDD TOC5 ;SET TOC5 TO NEXT INTERRUPT ADDD #PULS_LEN ;TIME STD TOC5 ; LDAA #$10 ;BEGIN THE A/D CONVERSION STAA ADCTL ;PROCESS LDAA #15 ;DELAY FOR OVER 32ms AD_DELAY DECA ; BNE AD_DELAY ; LDAB ADR2 STAB BAT_MEAS ;READ BATTERY, STORE TO VAR LDAB ADR1 ;GET DATA JUST MEASURED LDAA PORTB ;CHECK TO SEE IF WE JUST ANDA #%00000010 ;MEASURED PITCH OR ROLL BEQ IS_ROLL ; IS_PITCH LDX CUR_PITCH ;GET POINTER TO PITCH QUEUE STAB 0,X ;SAVE LATEST PITCH LDAB PORTB ANDB #ROLL_ON ;SET TO MEASURE ROLL NEXT STAB PORTB UPDATE_DATA LDD CUR_PITCH ;GET CURRENT Q POINTER SUBD #PITCHQ ;SUBTRACT Q STARTING POINT CPD #QUEUE_LENGTH-1 ;SEE IF WE ARE AT THE END OF THE Q BEQ RESET_PITCH ;SET CUR_PITCH BACK TO PITCHQ AND UPDATE LEVEL2 LDY CUR_PITCH ;INCREMENT CUR_PITCH POINTER INY STY CUR_PITCH ; BRA RET_OC5 ;DONE WITH PITCH UPDATE RESET_PITCH LDX #PITCHQ ;GET POINTER TO START OF Q STX CUR_PITCH ;RESET CURRENT PITCH POINTER LDY #PITCH_AVG LDAB #QUEUE_LENGTH JSR AVGLEVEL BRA RET_OC5 ;DONE WITH PITCH UPDATE IS_ROLL LDX CUR_ROLL ;GET POINTER TO Q STAB 0,X ;SAVE LATEST ROLL LDAB PORTB ORAB #PITCH_ON ;SET TO MEASURE PITCH NEXT STAB PORTB UPDATE_ROLL LDD CUR_ROLL ;GET CURRENT Q POINTER SUBD #ROLLQ ;SUBTRACT Q STARTING POINT CPD #QUEUE_LENGTH-1 ;SEE IF WE ARE AT END OF Q BEQ RESET_ROLL ;SET CUR_ROLL BACK TO PITCHQ AND UPDATE LEVEL2 LDY CUR_ROLL ;INCREMENT CUR_ROLL POINTER INY ; STY CUR_ROLL ; BRA RET_OC5 ;EXIT ISR RESET_ROLL LDX #ROLLQ ;RESET Q POINTER TO START OF Q STX CUR_ROLL ; LDY #ROLL_AVG ;GET AVERAGE VALUE LDAB #QUEUE_LENGTH JSR AVGLEVEL RET_OC5 RTI ;RETURN FROM OC5_ISR ****************************************************** * Subroutine: AVGLEVEL *************************** * * INPUT: X => BASE ADDRESS OF VALUES TO AVG (LEVEL ADDRESS) * Y => ADDRESS TO STORE AVG (LEVEL+1 ADDRESS) * B => NUMBER OF VALUES ON LEVEL ( MUST BE POWER OF 2) * OUTPUT: LEVEL+1 ADDRESS * DESTROYS: X,Y,A,B ******************************************************* AVGLEVEL PSHY CLRA PSHB ;SAVE TEMP FOR LATER PSHA ;CLEAR MSBYTE FOR Y PSHB ;TEMP FOR Y PSHA ;CLEAR MSBYTE FOR Y PULY ;HAS NUMBER OF VALUES ON LEVEL DECB ABX ;POINT TO LAST VALUE LDAB 0,X ;GET VALUE LEVEL_LOOP DEX ;POINT TO PREV VALUE DEY BEQ ADD_DONE ;EXIT WHEN ALL VALUES ADDED ADDB 0,X ;ADD PREV VALUE BCC LEVEL_LOOP INCA ;COUNT OVERFLOWS BRA LEVEL_LOOP ADD_DONE PULX ;GET # OF VALUES XGDX ;SWAP TEMPORARILY LSRD ;INITIAL DIVIDE BY 2 XGDX ;SWAP BACK BEQ COMP_AVG_DONE COMPUTE_AVG LSRD ;DIVIDE THE TOTAL BY 2 XGDX ;TRADE VALUES LSRD ;DIVIDE THE COUNTER BY TWO XGDX ;TRADE VALUES AGAIN BNE COMPUTE_AVG COMP_AVG_DONE PULY STAB 0,Y RTS ************************************************************************** * SUBROUTINE-INIT_IC1 * INPUTS: NONE * OUTPUTS: NONE * DESTROYS: NONE * DESCRIPTION: THIS SUROUTINE SETS UP THE IC1 FUNCTION TO BEGIN CAPTURING * ON A RISING EDGE, AND ENABLES INTERRUPTS ************************************************************************** * INIT_IC1 PSHA ;SAVE CONTENTS OF REGISTER A LDAA #%00010000 ;SET IC1 TO CAPTURE ON RISING EDGES STAA TCTL2 ; LDAA #%00000100 ;TURN OFF IC1'S FLAG STAA TFLG1 ; LDAA TMSK1 ;TURN ON IC1 INTERRUPTS, BUT DON'T INTERFERE ORAA #%00000100 ;WITH OTHER INTERRUPT BITS STAA TMSK1 ; PULA ;RESTORE THE CONTENTS OF REGISTER A RTS ;RETURN FROM THE SUBROUTINE ************************************************************************** * ISR - IC1_ISR * DESCRIPTION: HANDLES THE IC1 INTERRUPT REQUESTS ************************************************************************** * IC1_ISR LDAA TFLG1 ;CHECK FOR VALID INTERRUPT ANDA #%00000100 ;IF INVALID BEQ RET_IC1 ;RETURN FROM ISR STAA TFLG1 ;ELSE, CLEAR THE FLAG LDAA SUBSUM_TAK ;IF 1, THEN CONTROL IS SUBSUMED BNE RET_IC1 ;TO ANOTHER HIGH PRIORITY PROCESS LDAA TCTL2 ;CHECK TO SEE IF RISING OR FALLING EDGE WAS ANDA #%00100000 ;CAPTURED BEQ IC1_ROSE ;IF ZERO, RISING EDGE WAS CAPTURED IC1_FELL LDAA TCTL2 ;SET IC1 TO CAPTURE ON RISING EDGE NEXT ANDA #%11011111 ; ORAA #%00010000 ; STAA TCTL2 ; LDD TIC1 ;GET THE CAPTURED TIME SUBD IC1_START ;SUBTRACT THE PREVIOUSLY CAPTURED TIME CPD #PULLED_LEFT ;CHECK TO SEE IF STICK IS PULLED LEFT BLO IC1_MICR_ON ;IF SO, GIVE CONTROL TO MICROPROCESSOR CPD #PULLED_RIGHT ;CHECK TO SEE IF STICK IS PULLED RIGHT BHI IC1_RCVR_ON ;IF SO, GIVE CONTROL TO RECEIVER BRA RET_IC1 ;ELSE RETURN FROM ISR IC1_MICR_ON LDAA PORTB ;SET PORTB[0] TO ZERO WITHOUT DESTROYING ANDA #MICRO_ON ;OTHER PORTB VALUES STAA PORTB ; BRA RET_IC1 ;RETURN FROM ISR IC1_RCVR_ON LDAA PORTB ;SET PORTB[0] TO ONE WITHOUT DESTROYING ORAA #RCVR_ON ;OTHER PORTB VALUES STAA PORTB ; BRA RET_IC1 ;RETURN FROM ISR IC1_ROSE LDAA TCTL2 ;SET TO CAPTURE ON FALLING EDGE NEXT ANDA #%11101111 ; ORAA #%00100000 ; STAA TCTL2 ; LDD TIC1 ;GET THE TIME OF CAPTURE STD IC1_START ;AND STORE IT TO A TEMP VARIABLE RET_IC1 RTI ;RETURN FROM INTERRUPT