📄 usb_drv.asm
字号:
;-----------------------------------------------------------------------------
.dispatch:
mov A, REG[USB_EP0DATA+bmRequestType] ; Get bmRequestType
and A, E3h ; clear bits 4-3-2, these unused for our purposes
push A ; store value on the stack
asr A ; move bits 7-6-5 into 4-3-2's place
asr A ; "asr" instruction shift all bits one place to the right.
asr A ; Bit7 remains the same.
mov [USB_t2], A ; store shifted value
pop A ; get original value
or A, [USB_t2] ; or the two to get the 5-bit field
and A, 1Fh ; clear bits 7-6-5 (asr wraps bit7)
; Bit0 is loaded with a Zero. This results in multiplying
; the accumulator by 2, and the reason to mutiply it by 2
; is that each "jmp" instruction in the tables is two bytes long.
call USB_bmRequestType_Dispatch
jmp USB_EP0_ISR_EXIT ; And exit
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_EP0_IN
;
; DESCRIPTION: Handles an IN request. Depending on the state of the
; enumeration sequence it decides what to do next
;
USB_EP0_IN:
_USB_EP0_IN:
mov A, [USB_TransferType]
call USB_ControlInDispatch
jmp USB_EP0_ISR_EXIT ; And exit
USB_ControlInDispatch:
jacc USB_ControlInDispatchTable
.LITERAL
USB_ControlInDispatchTable:
jmp USB_Not_Supported_Local2 ; USB_TRANS_STATE_IDLE
jmp USB_ControlReadDataStage ; USB_TRANS_STATE_CONTROL_READ
jmp USB_ControlWriteStatusStage ; USB_TRANS_STATE_CONTROL_WRITE
jmp USB_NoDataControlStatusStage ; USB_TRANS_STATE_NO_DATA_CONTROL
.ENDLITERAL
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_EP0_OUT
;
; DESCRIPTION: Handles an OUT request. Depending on the state of the
; enumeration sequence it decides what to do next
;
USB_EP0_OUT:
_USB_EP0_OUT:
mov A, [USB_TransferType]
call USB_ControlOutDispatch
jmp USB_EP0_ISR_EXIT ; And exit
USB_ControlOutDispatch:
jacc USB_ControlOutDispatchTable
.LITERAL
USB_ControlOutDispatchTable:
jmp USB_Not_Supported_Local2 ; USB_TRANS_STATE_IDLE
jmp USB_ControlReadStatusStage ; USB_TRANS_STATE_CONTROL_READ
jmp USB_ControlWriteDataStage ; USB_TRANS_STATE_CONTROL_WRITE
jmp USB_NoDataControlError ; USB_TRANS_STATE_NO_DATA_CONTROL
.ENDLITERAL
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_InitControlRead
;
; DESCRIPTION: If the setup packet is determined to be requesting data
; this function is called to Initialize the state machine
; to handle upcoming IN requests
;
USB_InitControlRead:
mov [USB_TransferType], USB_TRANS_STATE_CONTROL_READ
; Check the transfer size against the request size
mov A, REG[USB_EP0DATA+wLengthHi] ; MSB of wLength
cmp A, [USB_TransferSize]
jnz .L1
mov A, REG[USB_EP0DATA+wLengthLo] ; LSB of wLength
cmp A, [USB_TransferSize+1]
jz .L9
.L1:
jnc .L9
;
mov [USB_TransferSize+1], A ;
mov A, REG[USB_EP0DATA+wLengthHi] ;
mov [USB_TransferSize], A ;
.L9:
mov [USB_Index], 0 ;
mov [USB_Index+1], 0 ;
mov [USB_EP0DataToggle], USB_CNT_TOGGLE
jmp USB_LoadEndpoint ;
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_ControlReadDataStage
;
; DESCRIPTION: Handles Loading of data for the non-zeroth IN request during
; a control read transaction
;
USB_ControlReadDataStage:
jmp USB_LoadEndpoint
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_ControlReadStatusStage
;
; DESCRIPTION: After all data has been transmitted the status stage is
; invoked
;
USB_ControlReadStatusStage:
mov [USB_TempMode], USB_MODE_STATUS_OUT_ONLY
mov [USB_TransferType], USB_TRANS_STATE_IDLE
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_NoDataStageControlTransfer
;
; DESCRIPTION: Send a 0 length packet to indicate the end of a control
; transfer or to acknowledge the receipt of data
;
USB_NoDataStageControlTransfer:
mov [USB_TransferType], USB_TRANS_STATE_NO_DATA_CONTROL
mov REG[USB_EP0CNT], 0
mov [USB_TempMode], USB_MODE_STATUS_IN_ONLY
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_InitControlWrite
;
; DESCRIPTION: In the case when the host wishes to write data to the device
; this function initializes the state machine to handle
; the subsequent out requests
;
USB_InitControlWrite:
mov A, [USB_DataSource] ; Need to make sure the destination is not ROM
cmp A, USB_DS_ROM
jz USB_Not_Supported_Local2
mov [USB_TransferType], USB_TRANS_STATE_CONTROL_WRITE
mov A, USB_CNT_TOGGLE ; Initialize the data toggle for next time
mov [USB_EP0DataToggle], A
mov REG[USB_EP0CNT], A
mov [USB_TempMode], USB_MODE_ACK_OUT_STATUS_IN
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_ControlWriteDataStage
;
; DESCRIPTION: Handles the non-zeroth OUT transfer of the a Control Write
; transaction
;
USB_ControlWriteDataStage:
mov A, REG[USB_EP0CNT] ; Get the count
and A, USB_CNT_TOGGLE ; Check the data toggle ;
xor A, [USB_EP0DataToggle] ;
xor [USB_EP0DataToggle], USB_CNT_TOGGLE ; Update data toggle
mov A,REG[USB_EP0CNT] ; Get the count
and A, 0x0F
sub A, 2 ; Count include the two byte checksum
mov [USB_t2], A ; Assume we have room to receive the whole packet
mov A, 0
cmp A, [USB_TransferSize] ; If the MSB has anything just use the count
jnz .L1
mov A, [USB_t2]
cmp A, [USB_TransferSize+1] ;
jz .L6
.L1:
jc .L6
mov [USB_t2], [USB_TransferSize+1]
.L6:
mov A, [USB_t2]
sub [USB_TransferSize+1],A ; Update the bytes remaining
sbb [USB_TransferSize], 0 ;
mov X,0 ; Start the index at 0
.RAM_COPY:
mov A, REG[X+USB_EP0DATA] ; Get the data
mvi [USB_DataPtr+1], A ; Store the data, bump the destination
inc X ; Bump the destination offset
mov A,X ; Are we done?
cmp A, [USB_t2]
jc .RAM_COPY ; Not done
mov [USB_TempMode], USB_MODE_ACK_OUT_STATUS_IN
ret
; Jump here on data toggle error
.error:
mov [USB_TransferType], USB_TRANS_STATE_IDLE ; This simply aborts the transfer
mov [USB_TempMode], USB_MODE_STALL_IN_OUT ;
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_ControlWriteStatusStage
;
; DESCRIPTION: Handles the Status stage of a control write by setting the
; endpoint to STALL IN/OUT
;
USB_ControlWriteStatusStage:
mov [USB_TransferType], USB_TRANS_STATE_IDLE ; The packet is done
mov [USB_TempMode], USB_MODE_STALL_IN_OUT ; Wait for the next SETUP
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_NoDataControlStatusStage
;
; DESCRIPTION:
;
USB_NoDataControlStatusStage:
; Dispatch to the proper handler
cmp [USB_fDataPending], USB_ADDRESS_CHANGE_PENDING
jnz .L1
; USB ADDRESS CHANGE
mov A, [USB_TransferBuffer] ; Get the pending data
or A, USB_ADDR_ENABLE ; Set the enable bit
mov REG[USB_ADDR], A ; Update the SIE address
jmp .EXIT
.L1:
.EXIT:
mov [USB_fDataPending], 0 ; Clear data pending
mov [USB_TempMode], USB_MODE_STATUS_IN_ONLY ; Wait for the next SETUP
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_NoDataControlError
;
; DESCRIPTION:
;
USB_NoDataControlError:
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_LoadEndpoint
;
; DESCRIPTION: Moves data from either RAM or ROM - depending on the request
; type and then places the appropriate number of bytes -
; depending on the request size into the endpoint FIFO.
; It finally sets up the endpoint to send data.
;
USB_LoadEndpoint:
mov A, [USB_TransferSize] ; Check to see if we have any
or A, [USB_TransferSize+1] ; more data to send
jnz .cont ; Jump if we have to send more data
; Flow here if there is no more data to send
cmp [USB_LastSize], 8 ; Was it a full packet?
jz .START_TRANSFER ; Jump if it was full (need to send a zero length)
; Flow here if we are entering the status stage
mov A,[USB_EP0DataToggle] ; move in the data toggle
xor [USB_EP0DataToggle], USB_CNT_TOGGLE ; Update the data toggle for next time
mov reg[USB_EP0CNT], A ; Set the count register
mov [USB_TempMode],USB_MODE_STATUS_OUT_ONLY ; Set the mode register
ret
; Jump here to determine how many bytes should we transfer
.cont:
; How many bytes should we transfer
cmp [USB_TransferSize], 0 ; Check the MSB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -