📄 hub_ep0.asm
字号:
RESUME_CODE:
$$IF$ IPORT
lcall FUNCTION_RESUME_ROUTINE ; Let function know that a resume signal was detected.
$$END$
clr GRSM ; CLear Resume Flag
clr GSUS ; CLear Suspend Flag
pop DR0
pop ACC
$$IF$ IPORT
pop PSW1
pop PSW
$$END$
reti
;----------------------------------------------------------------
;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
;SS SOF ISR
;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
;----------------------------------------------------------------
;COMMENT *------------------------------------------------------------
;Function name : SOF_ISR
;Brief Description : Service the SOF_ISR Interrupt
; : This routine simply displays the upper three bytes of the
; : SOF in the lower three bits of the LEDs on P1.
; : It does not affect the other LEDS. Very usefull
; : in determining when the function is receiveing SOFs
;Regs preserved : Reg. A is saved
;--------------------------------------------------------------------*
;SCOPE
SOF_ISR:
push PSW
push PSW1
push R11
$$IF$ IPORT
$$IF$ (EPATT11 == 1) || (EPATT12 == 1) || (EPATT13 == 1) || (EPATT14 == 1) || (EPATT15 == 1) || (EPATT16 == 1)
jnb ASOF, ExitSofIsr ; If this ASOF bit not set, the ISR could be a HUB. Go Check.
lcall EmbeddedFunctionSofRoutine
$$END$
$$END$
ExitSofIsr:
; The HX shares this ISR with the hub.
; Check to see if there is a HUB pending ISR
; By checking this last, we give the SOF interrupt
; higher priority.
jb HRXD0, HUB_ISR ;
jb HTXD0, HUB_ISR
ExitSofAndHubISR:
pop R11
pop PSW1
pop PSW
reti
;----------------------------------------------------------------
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;HH HUB ISR
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;----------------------------------------------------------------
;COMMENT *------------------------------------------------------------
;Function name : HUB_ISR
;Brief Description : Service the HUB_ISR Interrupt
; : This routine scans the interrupt pending bits in order
; : and branches to any routines that have pending interrupts.
; : After finishing the routine jumps back to the top of
; : the scanning loop to preserve interrupt priority.
; :
; : NOTE: The order of precidence is set by the order in which the
; : user places the checks.
; :
;Regs preserved : Reg. A, B & EPINDEX are saved
;--------------------------------------------------------------------*
;SCOPE
HUB_ISR:
push ACC
push B
push EPINDEX
ProcessHubEndpoints:
H_EP0:
mov A, HIFLG ; First check to see if this is EP0 Command
anl A, #03h ; As they require extra overhead. Mask off all but EP0 Interrupts
jz ExitHub
;----------------------------------------------------------------
;-- Process the EP0 COmmand in the correct order
;----------------------------------------------------------------
; If this an EP0 command then we need to process TX & RX
; ISRs in the correct order if, for whatever reason they occurred
; back to back. This happens in OHCI systems.
mov A, gbSetupSeqTX
cjne A, #SETUP_PHASE, CheckDataStatusStage
sjmp DoRxFirst ; If the status stage is Setup then check the RX First.
CheckDataStatusStage:
; Now check to see what stage the TX is in.
; If it is in the data stage then check it first.
; If it's in the status stage then check the RX first.
cjne A, #DATA_PHASE, DoRxFirst ; If current stage a data stage->a control read
; and we should process TX before RX ISR
;----------------------------------------------------------------
;-- Process the TX FIFO first
;----------------------------------------------------------------
DoTxFirst:
H_EP0_TXA:
jnb HTXD0, H_EP0_RXA
mov EPINDEX,#80h
lCall ProcessInToken ; 82930 has sent a packet to HC
ljmp ProcessHubEndpoints ; Look at all Interrupt flags again
H_EP0_RXA:
jnb HRXD0, ExitHub
mov EPINDEX,#80h
lCall ProcessOutToken ; 82930 has received a packet from HC
ljmp ProcessHubEndpoints ; Look at all Interrupt flags again
;--------------------------------------------------------------------------------
DoRxFirst:
;----------------------------------------------------------------
;-- Process the RX FIFO first
;----------------------------------------------------------------
H_EP0_RXB:
jnb HRXD0, H_EP0_TXB
mov EPINDEX,#80h
lCall ProcessOutToken ; 82930 has received a packet from HC
ljmp ProcessHubEndpoints ; Look at all Interrupt flags again
H_EP0_TXB:
jnb HTXD0, ExitHub
mov EPINDEX,#80h
lCall ProcessInToken ; 82930 has sent a packet to HC
ljmp ProcessHubEndpoints ; Look at all Interrupt flags again
;--------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;----------------------------------------------------------------
;-- Process the Other EPs next
;----------------------------------------------------------------
NonEp0ISR:
ExitHub:
pop EPINDEX
pop B
pop ACC
sjmp ExitSofAndHubISR
;COMMENT *------------------------------------------------------------
;Function name : ProcessOutToken
;Brief Description : Services all OUTs on EP0.
; : This routine checks to see if this is an OUT token oor
; : SETUP token. If a SETUP token then the Control COmmand
; : State machine is initilized to SETUP STAGE
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
ProcessOutToken:
mov A, EPINDEX
jb ACC.7, HubCommand
HubCommand:
anl HIFLG, #EP0_RX_CLR ; Clear the interrupt bit.
ProcCommand:
mov A, RXSTAT
jnb ACC.6, CheckOutStatusPhase ; Is this a setup packet??
; Now Check for Data still in FIFO.
; If this is true then the function
; did not see the ACK form the host.
mov A, TXFLG
anl A, #0C0h
jZ NoEP0Error
setb TXCLR
inc EP0_ERROR_CNT
NoEP0Error:
anl EPCON, #03Fh ; If a stall was set on EP0, this will clear it
; as stated in the new updates of the spec.
lCall SetupReceived
anl RXSTAT, #0BFh
sjmp ReturnProcessOutToken
CheckOutStatusPhase:
mov A, gbSetupSeqRX
cjne A, #STATUS_PHASE, CheckDataPhase ; Is this the status phase of a "GET"
; command?
setb RXFFRC ; Update receive FIFO state
setb TXCLR ; Flush the Transmit FIFOS in case
; a null packet is still left.
mov A, #SETUP_PHASE ; Update the state machine-Expect
; a setup packet
mov gbSetupSeqRX, A
mov gbSetupSeqTX, A
ljmp ReturnProcessOutToken
;---------------------------------------------------------------
; - Control Write Data Stage
;---------------------------------------------------------------
; If this is a control write command with a datastage then this
; routine will belcalled on all data stages of the control write.
; When all the data has been collected(Bytes received=wLength)
; the actual routine is called. The size of data is limited to this
; buffer length.
; THE CALLING CODE MUST THEN CALL SetUpControlWriteStatusStage to allow
; the status stage to continue. The user must NOT do this themselves.
; Later in the life of this code, other features will be added here.
CheckDataPhase:
cjne A, #DATA_PHASE, ReturnProcessOutToken ; Are we processing a Control Write,
; i.e. Set Descr...
; Added to handle control writes with data stages.
; When a control Write with a data stage is detected
; the data is placed in the buffer 'CntlWriteDataBuffer'
; When all the data
; has been collected(Bytes received=wLength) the actual routine is
; called. The size of data is limited to this buffer length.
;---------------------------------------------------------
;------------------- NOTE --------------------------------
;---------------------------------------------------------
; For this routine to work all the data must be stored below
; 100h as I am using byte addressing. Also, since 80-FF is used
; as SFRs and I don't want to for the user to use indirect
; addressing, the data must ne stored between 20h-7Fh.
; Also, these routines will only work for data sets of less than
; 256. But the above limitations put this the max much ower than
; this. MaxBuffer = (7F-20h-Other varaibles in this region)
push R0
mov A, #CntlWriteDataBuffer ; Get location of buffer
add A, CntlWriteDataPntr ; Add the offset
mov R0, A ; R0 now contains the location to start storing the
; data.
; Update the data stored in memory
mov A, RXCNTL ; Get number of bytes to move
add A, CntlWriteDataPntr ; Add number received
mov CntlWriteDataPntr, A ; update memory variable
mov A, RXCNTL
JZ RdDone ; If no data in the buffer, then exit.
ReadData:
mov @R0, RXDAT ; Get the data and store it.
inc R0
djnz ACC, ReadData
pop R0
RdDone:
setb RXFFRC ; Update receive FIFO state
; Now check to see if this was the last
; read by checking if (Bytes received=wLength)
mov A, CntlWriteDataPntr
cjne A, wLength+1, NeedMoreData ; If this is not equal to the expected, then jmp around.
; When all the data has been received, the
; other routines in this program will
; be called to process it.
ProcessControlWriteData:
push DPX ; Processing the jump table will
; corrupt DPX. Save it here
lcall DoJumpTable ; At this point all data has been
; stored and all we need to do now is to
; process it.
pop DPX ; Restore DPX
ljmp ReturnProcessOutToken
NeedMoreData:
CheckCommand2:
ReturnProcessOutToken:
Ret
;COMMENT *------------------------------------------------------------
;Function name : SetupReceived
;Brief Description : Service all Setup Tokens recd. on EP0
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
SetupReceived:
mov A, RXCNTL ; Get the no. of bytes
clr CY
subb A, #8 ; 8 is length of all setup packets.
JNZ ReturnSetup ; If less than 8 bytes recd.
; Return
; Since buffer will reside within the
; the first 255 bytes, I can use
; register indirect addressing
; Move FIFO to command buffer.
; Notice byte swapping of word fields
; For Word Fields make USB Little Endian words->'251 Big Endian words
clr EDOVW
mov COMMAND_BUFFER, RXDAT ; bmRequestType
mov COMMAND_BUFFER+1, RXDAT ; bRequest
mov COMMAND_BUFFER+3, RXDAT ; wValue LSB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -