?? slx11s.asm
字號:
;--------------------------------------------------------------------------
; slx11s.asm : SL11/SL811S basic IO subroutines
; Copyright: (c)1997 ScanLogic Corporation
; Revision: May/22/96 SNguyen Revised
; May/28/98 Clean-up
; Oct/23/00 revised
;
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; SL11/SL811S signal PIN map
;--------------------------------------------------------------------------
A0 REG P2.0
IRQ REG P2.1
NRST REG P2.2
NCS REG P2.3
NWRITE REG P2.4
NREAD REG P2.5
;==========================================================================
; SL11/SL811S WR
;==========================================================================
WrClock: .macro
CLR NWRITE
SETB NWRITE
.endm
;==========================================================================
; SL11/SL811S RD
;==========================================================================
RdClock: .macro
CLR NREAD
MOV A,P1
SETB NREAD
.endm
;==========================================================================
; SetInput
;==========================================================================
SetInput: .macro
mov p1,#ffh ;config P1 port for input
.endm
;==========================================================================
;MACRO sWrite
;==========================================================================
sWrite: .macro address,data
mov b,#address
mov a,#data
acall SL11Write
.endm
;==========================================================================
;MACRO sRead
;==========================================================================
sRead: .macro address
mov b,#address
acall SL11Read
.endm
;==========================================================================
;MACRO mEXIT
;==========================================================================
mEXIT .macro
ret ;if use ISR then change to rti
.endm
Poll_IRQ .macro
jnb IRQ,$ ;wait for SL11/SL811S Interrupt bit
.endm
;--------------------------------------------------------------------------
; SL11Addr: P1 = address of SL11/SL811S register or memory
;--------------------------------------------------------------------------
SL11Addr:
CLR A0 ;set A0 low for address
CLR NCS ;assert CS
WrClock ;togle the WR signal
SETB NCS ;negate CS
SETB A0 ;Set A0 high for Data
SetInput
ret
;--------------------------------------------------------------------------
; Input: B = address of SL11/SL811S register or memory
; Output: A = return data
; A = SL11Read(B)
;--------------------------------------------------------------------------
SL11Read:
mov P1,B
call SL11Addr ;Setup Address Write
SL11DataRd:
CLR NCS ;assert CS for read
RdClock
SETB NCS ;negate CS
ret
;--------------------------------------------------------------------------
; Input: B = address of SL11/SL811S register or memory
; Output: A = data to be written
; SL11Write(A,B)
;--------------------------------------------------------------------------
SL11Write:
mov P1,B
call SL11Addr ;Setup SL11/SL811S Address
SL11DataWr:
MOV P1,A ;Setup Data
CLR NCS
WrClock ;Toggle WR signal
SETB NCS ;negate CS
SetInput
ret
;--------------------------------------------------------------------------
; Check Image LineSize for DMA or PIO
;--------------------------------------------------------------------------
GetCmd:
mov a,#EP0Buf ;read from wValue
mov R0,#bmRequest ;get 8 bytes command
mov R1,#8h ;setup to transfer 8 bytes
;--------------------------------------------------------------------------
; Input: R0 = internal ram buffer
; R1 = count
; A = address of SL11/SL811S memory
; Ex: SL11ReadM(R0=buffer, R1=count, A=0x60)
;--------------------------------------------------------------------------
SL11ReadM:
mov P1,A
call SL11Addr
rloop:
CLR NCS
CLR NREAD
mov @R0,P1 ;write to internal ram
SETB NREAD
SETB NCS
inc R0 ;inc ram pointer
djnz R1,rloop
ret
;--------------------------------------------------------------------------
;SL11/SL811S Memory test
; return r7 = error, r7=0=success
;--------------------------------------------------------------------------
SL11MemTest:
mov r7,#0
mov b,#EP0Buf
mov r0,#sMemSize
lwrite:
mov a,b ;no auto increment mode
acall SL11Write
inc b
djnz r0,lwrite
mov r0,#sMemSize ;r0 the total length of SL memory
mov b,#EP0Buf ;b the beginning memory space of SL11/SL811S
lVerify:
acall SL11Read ;read verify
xrl a,b ;check for error
jz noerR0
inc r7 ;error
noerR0:
mov a,b ;write complement
cpl a
acall SL11Write ;write and read back verify
acall SL11Read
cpl a ;complement the result
xrl a,b
jz noerR1
inc r7 ;error
noerR1:
inc b
djnz r0,lVerify
mov r0,#sMemSize
mov a,#EP0Buf
mov P1,A
call SL11Addr ;setup address
uloop0:
call SL11DataWr ;write data
inc a
djnz r0,uloop0
mov r0,#sMemSize
mov b,#EP0Buf
mov a,b
mov P1,b
call SL11Addr ;setup address
uloop1:
call SL11DataRd ;read data
xrl a,b
jz noerR2
inc r7 ;error
noerR2:
inc b
djnz r0,uloop1
ret
;--------------------------------------------------------------------------
; Setup to receive EP0Len from host
;--------------------------------------------------------------------------
EP0Receive:
sWrite EP0XferLen,EP0Len
mov b,#EP0Control ; set Receive data from host
mov a,#03h
ajmp SL11Write
;--------------------------------------------------------------------------
;SL11Init:
;--------------------------------------------------------------------------
SL11Init:
mov DmaFlags,#0
sWrite USBAdd,0 ;set address = 0
sWrite EP0Counter,0 ;clear all endpoint counters
;setup EndPoint0
sWrite EP0Address,EP0Buf ;Setup EP0 Buffer
acall EP0Receive
;Use PIO on Endpoint 1 to send
sWrite EP1AAddress,uBufA ;Share SL11/SL811S buffer for Data0 packet
sWrite EP1BAddress,uBufB ;Share SL11/SL811S buffer for Data1 packet
;Use PIO on Endpoint 2 to receive
sWrite EP2AAddress,uBufA ;setup for PIO
sWrite EP2BAddress,uBufB
sWrite EP2AControl,0ah ;setup EP2 DATA0 for receiving
sWrite EP2BControl,042h ;setup EP2 DATA1 for receiving
sWrite EP2BXferLen,uXferLen
sWrite EP2AXferLen,uXferLen
;Use DMA on Endpoint 3 to send
sWrite EP3AAddress,uBufA ;Setup for DMA
sWrite EP3BAddress,uBufB
sWrite CtrlReg,3h ;write(5,3) enable SL11/SL811S DMA
sWrite IntEna,IntMask ;set interupt mask
sWrite IntStatus,ffh ;Clear the interrupt all flags
ret
;----------------------------------------------------------------------------
;EP0SendPkg from EPROM space point by DPTR
;input dptr = pointer to EPROM
; r0 = length
;----------------------------------------------------------------------------
EP0SendPkg:
mov b,#EP0XferLen ;Update the current length of EndPoint0
mov a,r0
acall SL11Write ;acall SL11Write
mov P1,#EP0Buf ;pointer to EP0Buf
call SL11Addr ;setup SL11/SL811S Addr
LoadSL11:
clr a
movc a,@a+dptr ;fetch const data from EPROM point by DPTR
call SL11DataWr
inc dptr
djnz R0,LoadSL11 ;repeat until R0=0
;----------------------------------------------------------------------------
;EP0Send Set ready to Send
;----------------------------------------------------------------------------
EP0Send:
mov b,#EP0Control ;Setup to send data to host
mov a,#47h
ajmp SL11Write ;acall SL11Write and return
;--------------------------------------------------------------------------
;SetupEP2:
;--------------------------------------------------------------------------
SetupEP2:
cpl EP2DataFlag
jb EP2DataFlag,EP2Toggle
sWrite EP2BControl,43h ;Setup to receive data from host on DATA1 EP2
ret
EP2Toggle:
sWrite EP2AControl,0bh ;Setup to receive data from host on DATA0 EP2
ret
;--------------------------------------------------------------------------
;SetupEP1:
; R0 = length
;--------------------------------------------------------------------------
SetupEP1:
cpl EP1DataFlag
jb EP1DataFlag,EP1Toggle
mov a,r0
mov b,#EP1BXferLen
acall SL11Write
sWrite EP1BControl,47h
ret
EP1Toggle:
mov a,r0
mov b,#EP1AXferLen
acall SL11Write
sWrite EP1AControl,0fh
ret
;---------------------------------------------------------------------------
; NOTE: if not used DMA these subroutine below can be removed
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;LineSize0: The low byte number to be transfed.
;LineSize1: The high byte number to be transfered.
;---------------------------------------------------------------------------
SL11EnableDma:
sWrite EP3AXferLen,uXferLen
sWrite EP3BXferLen,uXferLen
jnb EP3DataFlag,NoToggle
sWrite EP3AControl,4eh ;setup SL11/SL811S EndPoint3A and EndPoint3B
sWrite EP3BControl,06h ;Set EP 3B control reg.
sjmp DmaCommon
NoToggle:
sWrite EP3AControl,0eh ;setup SL11/SL811S EndPoint3A and EndPoint3B
sWrite EP3BControl,46h ;Set EP 3B control reg.
DmaCommon:
mov b,#DMACntLow ;Load the low byte of DMA total count.
mov a,LineSize0
acall SL11Write
mov b,#DMACntHigh ;Load the high byte of DMA total count.
mov a,LineSize1
ajmp SL11Write ;acall SL11Write and return
;--------------------------------------------------------------------------
; Special case for end point 0 in DMA cycle
;--------------------------------------------------------------------------
EP0Toggle:
Poll_IRQ ;wait for SL11/SL811S interrupt bit
sWrite IntStatus,01h ;Clear EP0 interrupts
acall EP0Receive ;Ready to receive command from EP0
ret
;--------------------------------------------------------------------------
; input: bmRequest
;--------------------------------------------------------------------------
EP0_Finish:
acall EP0Send ;toggle DATA bit by just send ACK
acall EP0Toggle
jnb bmRequest.7,HostWrSkip ;check bmRequest read/write direction
acall EP0Toggle
HostWrSkip:
ret
;--------------------------------------------------------------------------
; Read Image Line using DMA, until new command from EP0
;--------------------------------------------------------------------------
ReadDMALine:
acall EP0_Finish ;Host finish all the command
StartDMA:
MOV P1,wValue0 ;Write to EPP Address
call EPPAddrWr
acall SL11EnableDma ;kick off the DMA.
;----------------------------------------------------------------------
; SL11/SL811S DMA hardware will automatic set ARM bit to EP3A and EP3B
; software need to wait for DMA Interrupt Done.
; NOTE: CPU should not access SL11/SL811S IO, because the 8031 does not
; have the IO and DMA arbitration. However, the CPU can poll the
; SL11/SL811S IRQ bit or wait for the DMA Interrupt from SL11/SL811S chip.
;----------------------------------------------------------------------
Poll_IRQ ;wait DMA Done interrupt bit
sWrite IntStatus,10h ;Clr DMADone int flag.
wLoop:
sRead IntStatus ;Read the interrupt bit to see what happen
mov b,a
anl a,#HostMask
jnz ChkRem ;if host request abort dma
jb b.7,wLoop ;progress done check remainder
;----------------------------------------------------------------------
;SL11/SL811S DMA hardware doesnot support transfer the remainder. Software need
;to check to re-send the remainder last packet.
;Software need to know on the last packet, which DATA0/DATA1 is used
;for the re-send the last packet
;----------------------------------------------------------------------
ChkRem:
sRead DATASet
mov b,a
mov r1,#EP3BControl
mov r2,#EP3BXferLen
mov a,LineSize0
anl a,#3fh
jz SkipReArm
jb b.3,Set3B
mov r2,#EP3AXferLen
mov r1,#EP3AControl
Set3B:
mov b,r2
acall SL11Write ;write remainder to xfer length
mov b,r1
acall SL11Read ;Read Current EP3x control register
orl a,#1h ;Re-ARM current EP3x endpoint
acall SL11Write ;last remainder packet will be sent
SkipReArm:
sRead IntStatus
anl a,#HostMask
jnz HostAbort
mov b,r1
acall SL11Read
jb acc.0,SkipReArm ;check EP3 xferdone
sRead DATASet
jnb acc.3,sToggle
cpl EP3DataFlag
sToggle:
acall MovStepper
sjmp StartDMA
HostAbort:
acall MovStepper
ret
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -