;����������������������������������������������������������������������������Ŀ
;� SLIP PROTOCOL �
;� INTERRUPT HANDLER �
;� for 68HC16Z1 Microcontroller running MCX-16 �
;� �
;� compiled with Whitesmiths C compiler �
;� �
;� (c) June 1995 �
;� M. Lutfi �
;� Engineering Physics Dept. �
;� Faculty of Industrial Tech. �
;� Institut Technologi Bandung �
;� �
;������������������������������������������������������������������������������
.PROCESSOR M68HC16
.TITLE "Thesis Project : SLIP - communication handler"
.INCLUDE "hc16regs.mac"
.INCLUDE "mcx16.mac"
.INCLUDE "lgrset.mac"
;*******************************************************************************
;* SCI DRIVER DATA VARIABLES *
;*******************************************************************************
.PUBLIC _in_char, _out_char
.psect _data
_in_char: .BYTE (1)
_out_char: .BYTE (1)
_dest_temp: .BYTE (1)
_src_temp: .BYTE (1)
.psect _text
.even
.LIST + .MACRO
;*******************************************************************************
;* *
;* S C I I N P U T D R I V E R *
;* *
;*******************************************************************************
.PUBLIC _sciidrv
_sciidrv:
rdclr: ldd SCSR ; Get current status of SCI
bitb #RDRF ; See if receive data ready
beq scirdy ; if not SCI is a
ldab SCDR ; Read input data
bra rdclr ; Loop until clear
scirdy: andp #0FF1Fh ; Turn interrupts on again
inloop: ldab #1 ; bank 1
tbek ; EK = 1
tbxk ; XK = 1 (K=$11xx)
ldab #SCI_RCV_SEMA
ldaa #MCX_WAIT_ ; Wait for input character
swi
ldaa _in_char ; Get input character captured by isr
ldx #_src_temp ; Move it to safe place
staa 0,x
ldab #SCI_RCV_Q ; Then move the character into SCIIQ
ldaa #MCX_ENQUEUE_W_
swi
bra inloop ; Loop forever
;*******************************************************************************
;* *
;* S C I O U T P U T D R I V E R *
;* *
;*******************************************************************************
sciodrv: ldab #0Fh
tbek ; EK=F (K=$Fxxx)
ldab #1
tbxk ; XK=1 (K=$F1xx)
scioloop:
ldx #_dest_temp
ldab #SCI_TRM_Q ; Get next character from SCI_TRM_Q and put it into
ldaa #MCX_DEQUEUE_W_ ; _dest_temp as temporary location
swi
ldab 0,x ; Get the character
cmpb #0Ah ; New Line?
bne notnl ; Branch if not "\n"
ldd SCSR ; Get SCI status
ldaa #0Dh
staa SCDR+1 ; Output a "\r"
ldd #RIE+RE+TE+TIE
std SCCR1 ; Enable transmitter interrupts
; ldab #RIE+RE+TE+TIE
; stab SCCR1+1 ; Enable transmitter interrupts
ldab #SCI_TRM_SEMA ; Wait for it to be output completely
ldaa #MCX_WAIT_
swi
notnl: ldd SCSR ; Read status
ldaa 0,x ; Get character to output
staa SCDR+1 ; Output it
ldd #RIE+RE+TE+TIE
std SCCR1 ; Enable transmitter interrupts
; ldab #RIE+RE+TE+TIE
; stab SCCR1+1 ; Enable transmitter interrupts
ldab #SCI_TRM_SEMA ; Wait for it to be output completely
ldaa #MCX_WAIT_
swi
bra scioloop ; Loop forever
;*******************************************************************************
;* *
;* S C I I N T E R R U P T S E R V I C E R O U T I N E *
;* *
;*******************************************************************************
sciisr: orp #INTS_OFF ; Save the interrupt context
pshm d,e,x,y,z,k
ldab #1
tbek ; EK=1 (K=$1xxx)
tbyk ; YK=1 (K=$1x1x)
tbzk ; ZK=1 (K=$1x11)
clrb
tbxk ; XK=0 (K=$1011)
ldx 0000h ; x = [$10000]
tst 000Ah
bne notlvl0
ldy 0004h ; y = [$10004]
sts 8,y ; [y+8] = SP
lds 14h,x ; SP = [X+20]
notlvl0: inc 000Ah ; [$1000A] = [$1000A]+1
andp #SCIINTON ; Interrupts back on
ldz 12h,x
ldab #0Fh ; EK = F (K=$Fx11)
tbek
ldab #1
tbxk ; XK = 1 (K=$F111)
ldx #0000 ;h
ldy #_in_char ; y = &inchar
ldd SCCR1 ; If TDRE is set, see if SCCR1 has TIE set
bitb #TIE
beq notout ; If not, this is not an output interrupt
ldd SCSR ; Check SCI status register for TDRE
bita #TDRE
beq chkrd ; TDRE not set
ldd #RIE+RE+TE ; If so, this is a transmitter interrupt, turn
; TIE off now that the character is out
std SCCR1 ; Update SCCR1. That takes care of the output side
ldd SCSR ; Now treat a possible input interrupt that is
; simultaneous with the output. Reread the status
bitb #RDRF ; Check for RDRF set
beq noin ; Branch if no input occurred
ldd SCDR ; Yes it did. Read the input character
andb #7Fh ; Strip it to 7 bits
stab 0,y ; Store in temporary location (inchar)
PSHSEMA SCI_TRM_SEMA ; Put SCI_TRM_SEMA into Signal List
noin: ldaa #SCI_TRM_SEMA ; Now signal the SCI output semaphore
jmp isrrtn
notout:
ldd SCSR ; Read status again
chkrd:
bitb #RDRF ; See if this is an input interrupt. Check RDRF
beq notin ; It is not an input interrupt. So what was it?
ldd SCDR ; If it was an input interrupt, get the character
stab 0,y ; Store in temporary location (inchar)
; That takes care of the input. Now see if there
; was a simultaneous output interrupt
ldd SCSR ; Check SCI status register for TDRE
bita #TDRE
beq noout ; TDRE not set
ldd SCCR1 ; If TDRE is set, see if SCCR1 has TIE set
bitb #TIE
beq noout ; If not, this cannot be an output interrupt
ldd #RIE+RE+TE ; If so, this is a transmitter interrupt, turn
; TIE off now that the character is out
std SCCR1 ; Update SCCR1
PSHSEMA SCI_TRM_SEMA ; Signal SCI Output Semaphore
noout: ldaa #SCI_RCV_SEMA ; Now signal the input semaphore
jmp isrrtn
notin: clra ; This wasn't a recognizable SCI interrupt
jmp isrrtn
;*******************************************************************************
;* SCI VECTOR *
;*******************************************************************************
.END
No comments:
Post a Comment