0001 * 68HC11 EVBU Interval Timer Program 0002 * 0003 * Program Description: 0004 * This program accepts two digital inputs and delivers one digital output. The inputs 0005 * correspond to projectile crossings across two timing stations. The program measures 0006 * the time interval between the two crossings and supplies a single pulse which starts 0007 * at a time after the second event which equals the time interval between the two events. 0008 * The single output pulse is fixed length of 1 millisecond (msec). The value of the time 0009 * interval is outputted on the SCI serial port as a decimal number of microseconds (usec). 0010 * Diagnostic information can be enabled by setting a flag. 0011 * 0012 * PA0/IC3 is used for A input. 0013 * PA1/IC2 is used for B input. 0014 * PA4/OC4 is used for pulse output. 0015 * PA5/OC3 is used for timeout interrupt. 0016 * 0017 * Revision History 0018 * 0019 * Version 1.0 12/15/93 initial program 0020 * 0021 0022 **************** 0023 * EQUATES * 0024 **************** 0025 0000 RAMST EQU $0000 start of ram 0026 0100 URAMST EQU $0100 start of user ram (not used by Buffalo) 0027 1000 REGST EQU $1000 start of registers 0028 e000 ROMST EQU $E000 start of rom 0029 b600 EEPROMST EQU $B600 start of eeprom 0030 00c4 VECTORS EQU $00C4 interrupt vector jump table 0031 1000 REGBASE EQU $1000 start of register block for indirect addressing 0032 0033 * Buffalo support routines 0034 e00a BUFFALO EQU ROMST+$0A Buffalo entry is just past the beginning of ROM 0035 ffa9 INIT EQU $FFA9 Initialize Serial I/O port, 8 bits, 1 stop & no parity 0036 ffd0 VECINIT EQU $FFD0 Initialize RAM vector jump table 0037 ffa0 UPCASE EQU $FFA0 Convert character in A register to upper case 0038 ffcd INCHAR EQU $FFCD Input a character to the A register & echo 0039 ffaf OUTPUT EQU $FFAF Output a character in the A register 0040 ffc4 OUTCRLF EQU $FFC4 Output a CR and LF 0041 ffca OUTSTRG EQU $FFCA Output a string pointed by X until EOT 0042 ffbb OUTBYTE EQU $FFBB Output a byte pointed by X as 2 hex characters 0043 ffc1 OUTWORD EQU $FFC1 Output a word pointed by X as 4 hex char's & a space 0044 ffb2 OUTLEFT EQU $FFB2 Output the left nibble in the A register in ASCII 0045 ffb5 OUTRIGHT EQU $FFB5 Output the right nibble in the A register in ASCII 0046 ff7c WARMST EQU $FF7C Buffalo warm start, skip "buffalo..." message 0047 0048 * Single character definitions 0049 0004 EOT EQU $04 END OF TEXT character 0050 0007 BELL EQU $07 BELL character 0051 000d CR EQU $0D carrige return character 0052 0053 * SCI registers 0054 102b BAUD EQU $102B baud rate selector 0055 102c SCCR1 EQU $102C 9 bit format & wake up selector 0056 102d SCCR2 EQU $102D main SCI controls 0057 102e SCSR EQU $102E two TX & five RC status flags 0058 102f SCDR EQU $102F bidirectional data buffer 0059 0060 * Main timer & real time interrupt registers 0061 100e TCNT EQU $100E timer counter (double) register 0062 1020 TCTL1 EQU $1020 timer control register #1 0063 1021 TCTL2 EQU $1021 timer control register #2 0064 1023 TFLG1 EQU $1023 timer flag register #1 0065 1025 TFLG2 EQU $1025 timer flag register #2 0066 1022 TMSK1 EQU $1022 mask register #1 0067 1024 TMSK2 EQU $1024 mask register #2 0068 1010 TIC1 EQU $1010 input compare time capture (double) register 0069 1012 TIC2 EQU $1012 input compare time capture (double) register 0070 1014 TIC3 EQU $1014 input compare time capture (double) register 0071 1016 TOC1 EQU $1016 output compare time capture (double) register 0072 1018 TOC2 EQU $1018 output compare time capture (double) register 0073 101a TOC3 EQU $101A output compare time capture (double) register 0074 101c TOC4 EQU $101C output compare time capture (double) register 0075 0076 * Parallel I/O registers 0077 1000 PORTA EQU $1000 port A bits, inputs on bit 0 & 1 0078 1004 PORTB EQU $1004 port B bits, LEDs on bit 0, 1, 2 & 3 0079 0080 * Other registers 0081 1035 BPROT EQU $1035 eeprom block protect register 0082 1039 OPTION EQU $1039 system configuration options register 0083 103c HIPRIO EQU $103C highest priority interrupt register 0084 0085 * Buffalo RAM locations 0086 0065 STACK EQU $0065 top of Buffalo stack 0087 00a7 IODEV EQU $00A7 0=sca, 1=acia, 2=duarta, 3=duartb 0088 00a8 EXTDEV EQU $00A8 0=none, 1=acia, 2=duart 0089 00a9 HOSTDEV EQU $00A9 0=sci, 1=acia, 3=duartb 0090 0091 **************** 0092 * RAM * 0093 **************** 0094 0100 ORG URAMST don't interfere with Buffalo 0095 0100 STATE RMB 1 -1=RESET, 0=READY, 1=ARMED 0096 0101 ATIME RMB 2 clock time when A edge occured 0097 0103 BTIME RMB 2 clock time when B edge occured 0098 0105 DELAY RMB 2 delta time between BTIME & ATIME 0099 0107 PSTART RMB 2 clock time for start of output pulse 0100 0109 PSTOP RMB 2 clock time for end of output pulse 0101 0102 ******************************* 0103 * INTERRUPT VECTOR JUMP TABLE * 0104 ******************************* 0105 00c4 ORG VECTORS 0106 00c4 JSCI RMB 3 asynchronous communication interface 0107 00c7 JSPI RMB 3 synchronous peripheral interface 0108 00ca JPAIE RMB 3 pulse accumulator input edge 0109 00cd JPAO RMB 3 pulse accumulator overflow 0110 00d0 JTOF RMB 3 timer overflow 0111 00d3 JOC5 RMB 3 timer output compare 5 0112 00d6 JOC4 RMB 3 timer output compare 4 0113 00d9 JOC3 RMB 3 timer output compare 3 0114 00dc JOC2 RMB 3 timer output compare 2 0115 00df JOC1 RMB 3 timer output compare 1 0116 00e2 JIC3 RMB 3 timer input capture 3 0117 00e5 JIC2 RMB 3 timer input capture 2 0118 00e8 JIC1 RMB 3 timer input capture 1 0119 00eb JRTI RMB 3 real time interrupt 0120 00ee JIRQ RMB 3 non-maskable interrupt 0121 00f1 JXIRQ RMB 3 XIRQ 0122 00f4 JSWI RMB 3 software interupt 0123 00f7 JILLOP RMB 3 illegal opcode 0124 00fa JCOP RMB 3 COP fail 0125 00fd JCLM RMB 3 clock monitor 0126 0127 **************** 0128 * EEPROM * 0129 **************** 0130 0131 b600 ORG EEPROMST 0132 **************** 0133 * START - This is where the program starts out after reset. 0134 * All initialization is done here including: 0135 * timer registers setup 0136 * timer interrupt service routines 0137 * SCI registers setup & 0138 * I/O setup. 0139 **************** 0140 0141 b600 7f 00 a8 START CLR EXTDEV no external device 0142 b603 7f 00 a7 CLR IODEV use the SCI supervisor routine 0143 b606 7f 00 a9 CLR HOSTDEV use the SCI port 0144 b609 8e 00 65 LDS #STACK set up monitor stack 0145 b60c bd ff d0 JSR VECINIT initialize the interrupt table 0146 b60f bd ff a9 JSR INIT initialize the serial port 0147 b612 ce b6 8b LDX #AEDGE address of first rising edge interrupt routine 0148 b615 df e3 STX JIC3+$01 install at timer input capture 3 0149 b617 ce b6 a6 LDX #BEDGE address of second rising edge interrupt routine 0150 b61a df e6 STX JIC2+$01 install at timer input capture 2 0151 b61c ce b7 24 LDX #TIMEOUT address of timeout interrupt routine 0152 b61f df da STX JOC3+$01 install at timer output capture 3 0153 b621 86 03 LDAA #$03 PA0/IC3 & PA1/IC2 0154 b623 b7 10 22 STAA TMSK1 enable interrupts 0155 b626 7f 10 24 CLR TMSK2 no timer overflow, RTI or PA events; prescale = 0 0156 b629 7f 10 20 CLR TCTL1 disable all output compares 0157 b62c 86 05 LDAA #$05 enable rising edge on PA0/IC3 & PA1/IC2 0158 b62e b7 10 21 STAA TCTL2 0159 0160 b631 bd ff c4 JSR OUTCRLF 0161 b634 ce b7 69 LDX #MSGSTRT initial ID message 0162 b637 bd ff ca JSR OUTSTRG 0163 b63a bd ff c4 JSR OUTCRLF 0164 0165 b63d 7f 01 00 CLR STATE start up in RESET state 0166 b640 7a 01 00 DEC STATE STATE = -1 0167 0168 b643 0e MAIN CLI enable interrupts 0169 b644 ce b7 91 LDX #MSGREADY READY message 0170 b647 bd ff ca JSR OUTSTRG 0171 b64a bd ff c4 JSR OUTCRLF 0172 b64d bd ff c4 JSR OUTCRLF 0173 0174 b650 bd b6 82 LOOP JSR DOLEDS update the LEDs 0175 b653 b6 01 00 LDAA STATE check the current state 0176 b656 2c f8 BGE LOOP just loop if IDLE or ARMED 0177 b658 0f SEI if RESET then disable interrupts 0178 b659 ce b7 88 LDX #MSGRESET entering RESET message 0179 b65c bd ff ca JSR OUTSTRG 0180 b65f bd ff c4 JSR OUTCRLF 0181 b662 b6 10 22 LDAA TMSK1 get current value of register 0182 b665 84 df ANDA #$DF disable timeout interrupt (OC3) 0183 b667 b7 10 22 STAA TMSK1 store it 0184 b66a 86 33 LDAA #$33 clear any pending interrupts 0185 b66c b7 10 23 STAA TFLG1 0186 0187 b66f ce b7 9a LDX #MSGWAITLL "waiting for lows" message 0188 b672 bd ff ca JSR OUTSTRG 0189 b675 bd ff c4 JSR OUTCRLF 0190 0191 b678 bd b6 82 WAIT JSR DOLEDS always update the LEDs 0192 b67b 26 fb BNE WAIT keep looping if either is high 0193 b67d 7f 01 00 CLR STATE advance to the IDLE state (=0) 0194 b680 20 c1 BRA MAIN now both are low 0195 0196 **************** 0197 * DOLEDS- Read the input lines on port A and turn on the LEDs on port B. 0198 * The CC register is left with a sample of the inputs. 0199 **************** 0200 b682 b6 10 00 DOLEDS LDAA PORTA 0201 b685 84 03 ANDA #$03 mask off bit 0 0202 b687 b7 10 04 STAA PORTB stuff it in the LED register 0203 b68a 39 RTS return now, CC register is set 0204 0205 **************** 0206 * AEDGE - Interrupt service routine for PA0/IC3 rising edge 0207 **************** 0208 b68b fc 10 14 AEDGE LDD TIC3 read clock time 0209 b68e fd 01 01 STD ATIME store it 0210 0211 b691 7f 01 00 CLR STATE 0212 b694 7c 01 00 INC STATE move to ARMED state (=1) 0213 0214 b697 fc 01 01 LDD ATIME timeout interrupt is one roll over from A edge 0215 b69a fd 10 1a STD TOC3 store in output compare register 0216 b69d 86 23 LDAA #$23 select OC3, IC2 & IC3 bits 0217 b69f b7 10 23 STAA TFLG1 clear any pending interrupts 0218 b6a2 b7 10 22 STAA TMSK1 enable interrupts 0219 0220 b6a5 3b RTI return 0221 0222 **************** 0223 * BEDGE - Interrupt service routine for PA1/IC2 rising edge 0224 **************** 0225 b6a6 b6 01 00 BEDGE LDAA STATE check the current state 0226 b6a9 80 01 SUBA #$01 should be in STATE = 1 0227 b6ab 27 0b BEQ BOK everything is just fine 0228 b6ad ce b7 ab LDX #MSGBAERR 0229 b6b0 bd ff ca JSR OUTSTRG 0230 b6b3 bd ff c4 JSR OUTCRLF 0231 b6b6 20 75 BRA CLEANUP finish it up in TIMEOUT 0232 0233 b6b8 fc 10 12 BOK LDD TIC2 read clock time 0234 b6bb fd 01 03 STD BTIME store it 0235 b6be b3 01 01 SUBD ATIME subtract the A edge 0236 b6c1 fd 01 05 STD DELAY now you have the delay time 0237 b6c4 f3 01 03 ADDD BTIME add to it the B edge 0238 b6c7 fd 01 07 STD PSTART and you have the pulse start time 0239 b6ca c3 07 d0 ADDD #2000 add to it 2000 clock ticks (1 msec) 0240 b6cd fd 01 09 STD PSTOP and you have the pulse end time 0241 0242 b6d0 b6 10 04 LDAA PORTB 0243 b6d3 8a 04 ORA #$04 0244 b6d5 b7 10 04 STAA PORTB 0245 0246 * put output pulse routine here 0247 0248 b6d8 86 0c LDAA #$0C successful compare sets OC4 0249 b6da b7 10 20 STAA TCTL1 load the register 0250 b6dd 86 10 LDAA #$10 0251 b6df b7 10 23 STAA TFLG1 clear any pending OC4F flag 0252 b6e2 fc 01 07 LDD PSTART get the pulse start time 0253 b6e5 b7 10 1c STAA TOC4 set OC4 to trigger then 0254 b6e8 b6 10 23 LOOP1 LDAA TFLG1 get the output compare flags 0255 b6eb 84 10 ANDA #$10 mask out OC4 0256 b6ed 27 f9 BEQ LOOP1 if clear keep waiting 0257 b6ef 86 08 LDAA #$08 successful compare clears OC4 0258 b6f1 b7 10 20 STAA TCTL1 load the register 0259 b6f4 86 10 LDAA #$10 0260 b6f6 b7 10 23 STAA TFLG1 clear OC4F 0261 b6f9 fc 01 09 LDD PSTOP get the pulse stop time 0262 b6fc b7 10 1c STAA TOC4 set OC4 to trigger then 0263 b6ff b6 10 23 LOOP2 LDAA TFLG1 get the output compare flags 0264 b702 84 10 ANDA #$10 mask out OC4 0265 b704 27 f9 BEQ LOOP2 if clear keep waiting 0266 0267 b706 fc 01 05 LDD DELAY get the delay time 0268 b709 04 LSRD divide by two to get 0269 b70a fd 01 05 STD DELAY time in usec 0270 b70d ce b7 b7 LDX #MSGINTER output the message 0271 b710 bd ff ca JSR OUTSTRG 0272 b713 ce 01 05 LDX #DELAY now output the value 0273 b716 bd b7 41 JSR SENDDEC 0274 b719 ce b7 a5 LDX #MSGUSEC lastly add the units 0275 b71c bd ff ca JSR OUTSTRG 0276 b71f bd ff c4 JSR OUTCRLF 0277 0278 b722 20 09 BRA CLEANUP finish it up in TIMEOUT 0279 0280 **************** 0281 * TIMEOUT - Interrupt service routine for A to B timeout 0282 **************** 0283 b724 ce b7 7e TIMEOUT LDX #MSGTMOUT notify that a timeout occurred 0284 b727 bd ff ca JSR OUTSTRG 0285 b72a bd ff c4 JSR OUTCRLF 0286 0287 b72d 7f 01 00 CLEANUP CLR STATE change state to RESET (=-1) 0288 b730 7a 01 00 DEC STATE 0289 b733 86 33 LDAA #$33 clear all pending interrupts 0290 b735 b7 10 23 STAA TFLG1 0291 b738 b6 10 22 LDAA TMSK1 get current value of register 0292 b73b 84 df ANDA #$DF disable timeout interrupt (OC3) 0293 b73d b7 10 22 STAA TMSK1 store it 0294 b740 3b RTI return from interrupt 0295 0296 **************** 0297 * SENDDEC(X)- Output the value pointed at by X as a decimal number 0298 **************** 0299 b741 ec 00 SENDDEC LDD 0,X load D with the number to be sent 0300 b743 ce 27 10 LDX #10000 load X with 10000 0301 b746 bd b7 5f JSR DECOUT subroutine for decimal digit output 0302 b749 ce 03 e8 LDX #1000 load X with 1000 0303 b74c bd b7 5f JSR DECOUT subroutine for decimal digit output 0304 b74f ce 00 64 LDX #100 load X with 100 0305 b752 bd b7 5f JSR DECOUT subroutine for decimal digit output 0306 b755 ce 00 0a LDX #10 load X with 10 0307 b758 bd b7 5f JSR DECOUT subroutine for decimal digit output 0308 b75b bd b7 60 JSR DOIT subroutine just for simple output 0309 b75e 39 RTS return from the subroutine 0310 0311 b75f 02 DECOUT IDIV quotient in X & remainder in D 0312 b760 8f DOIT XGDX swap 'em 0313 b761 17 TBA move the value to be sent to A 0314 b762 8b 30 ADDA #$30 add ASCII bias 0315 b764 bd ff af JSR OUTPUT and send it 0316 b767 8f XGDX swap 'em back 0317 b768 39 RTS 0318 0319 **************** 0320 * TABLES 0321 **************** 0322 b769 49 6e 74 65 72 76 MSGSTRT FCC 'Interval Timer, V1.0' 61 6c 20 54 69 6d 65 72 2c 20 56 31 2e 30 0323 b77d 04 FCB EOT 0324 b77e 54 69 6d 65 20 6f MSGTMOUT FCC 'Time out!' 75 74 21 0325 b787 04 FCB EOT 0326 b788 52 65 73 65 74 2e MSGRESET FCC 'Reset...' 2e 2e 0327 b790 04 FCB EOT 0328 b791 52 65 61 64 79 2e MSGREADY FCC 'Ready...' 2e 2e 0329 b799 04 FCB EOT 0330 b79a 57 61 69 74 69 6e MSGWAITLL FCC 'Waiting...' 67 2e 2e 2e 0331 b7a4 04 FCB EOT 0332 b7a5 20 75 73 65 63 MSGUSEC FCC ' usec' 0333 b7aa 04 FCB EOT 0334 b7ab 42 20 62 65 66 6f MSGBAERR FCC 'B before A!' 72 65 20 41 21 0335 b7b6 04 FCB EOT 0336 b7b7 49 6e 74 65 72 76 MSGINTER FCC 'Interval is: ' 61 6c 20 69 73 3a 20 0337 b7c4 04 FCB EOT 0338