;*****************************************************************************
;* *
;* S C I D R I V E R M O D U L E *
;* UNDER HC16 MULTITASKING EXECUTIVE (MCX16) *
;* WITH SLIP PROTOCOL *
;* *
; Compiled with Whitesmith Cross Assember ver 1.9 *
;* (c) 11 December 1994 *
;* by M. Lutfi *
;* Thesis Project *
;* Instrumentation and Controls lab. *
;* Department of Engineering Physics *
;* FACULTY OF INDUSTRIAL TECHNOLOGY *
;* BANDUNG INSTITUTE OF TECHNOLOGY *
;*****************************************************************************
.PROCESSOR M68HC16
.TITLE "SCI DRIVER MODULE"
.INCLUDE "lgrset.s"
.PAGE "SCIDRV"
;*******************************************************************************
;* *
;* S C I I N P U T D R I V E R *
;* with SLIP data-link layer protocol *
;*******************************************************************************
sciidrv:
orp #INTS_OFF ; Turn off interrupts while enabling SCI
ldab #0Fh
tbek ; EK = F (K=Fxxxh)
ldd #008Ah
std QMCR ; Set IARB=10 for intermodule bus arbitration
ldd QILR ; Get content of QSM Interrupt Levels Register
anda #0E8h ; Clear out ILSCI field
oraa #SCIINTLV ; Set SCI interrupt level in ILSCI field
ldab #SCIINTV ; Load SCI Interrupt Vector #
std QILR ; Update QILR
ldd #RIE+RE+TE ; Receiver enabled with interrupts active,
; Transmitter enabled without interrupts,
; 1 Start Bit, 1 Stop Bit, 8 Data Bits
std SCCR1 ; Set up SCI operating conditions
ldd #BR9600 ; Set up 9600 baud rate
std SCCR0
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
tbek ; EK = 1
tbxk ; XK = 1 (K=11xxh)
ldab #SCIISEMA
ldaa #MCX_WAIT ; Wait for input character
swi
ldaa inchar ; Get input character captured by isr
ldx #EQ3src ; Move it to safe place
staa 0,x
ldab #SCIIQ ; Then move the character into SCIIQ
ldaa #MCX_ENQUEUE_W
swi
bra inloop ; Loop forever
.PAGE "SCIDRV"
;*******************************************************************************
;* *
;* S C I O U T P U T D R I V E R *
;* *
;*******************************************************************************
sciodrv: ldab #0Fh
tbek ; EK=F (K=Fxxxh)
ldab #1
tbxk ; XK=1 (K=F1xxh)
scioloop: ldx #DQ4dest
ldab #SCIOQ ; Get next character from SCIOQ and put it into
ldaa #MCX_QUEUE_W ; DQ4dest 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 #SCIOSEMA ; 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 #SCIOSEMA ; Wait for it to be output completely
ldaa #MCX_WAIT
swi
bra scioloop ; Loop forever
.PAGE "SCIDRV"
;�����������������������������������������������������������������������������Ŀ
;� �
;� 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 �
;� �
�������������������������������������������������������������������������������
.MACRO pshsema
ldab ?1
orp #INTS_OFF
lde 06h,x
stab e,z
incw 06h,x
andp #SCIINTON
.EXITM
sciisr:
orp #INTS_OFF ; Save the interrupt context
pshm d,e,x,y,z,k
ldab #1
tbek ; EK=1 (K=1xxxh)
tbyk ; YK=1 (K=1x1xh)
tbzk ; ZK=1 (K=1x11h)
clrb
tbxk ; XK=0 (K=1011h)
ldx 0000h
tst 000Ah
bne notlvl0
ldy 0004
sts 8,y
lds 14h,x
notlvl0: inc 000Ah
andp #SCIINTON ; Interrupts back on
ldz 12h,x
ldab #0Fh ; EK = F (K=$Fx11)
tbek
ldab #1
tbxk ; XK = 1 (K=$F111)
ldx #0000
ldy #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 SCIISEMA ; Put SCIISEMA into Signal List
noin: ldaa #SCIOSEMA ; 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
andb #7Fh ; Strip it to 7 bits
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 SCIOSEMA ; Signal SCI Output Semaphore
noout: ldaa #SCIISEMA ; Now signal the input semaphore
jmp isrrtn
notin: clra ; This wasn't a recognizable SCI interrupt
jmp isrrtn
.PAGE "SCIDRV"
;���������������������������������������������������������������������������Ŀ
;� SCI VECTOR �
;�����������������������������������������������������������������������������
.PSECT _text
.ADDR sciisr
;���������������������������������������������������������������������������Ŀ
;� SCI DRIVER DATA VARIABLES �
;�����������������������������������������������������������������������������
.PSECT _data ; 003FDh
inchar: .BYTE 1
DQ4dest: .BYTE 1
EQ3src: .BYTE 1
.END
No comments:
Post a Comment