📄 myusb_drv.asm
字号:
MOV A, REG[myUSB_EP0DATA+wLengthHi] ;
MOV [myUSB_TransferSize], A ;
.L9:
MOV [myUSB_TransferByteCount], 0;
MOV [myUSB_TransferByteCount+1], 0 ;
OR [myUSB_EP0DataToggle], 1 ; setup EP0 data toggle
JMP myUSB_LoadEndpoint ;
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_ControlReadDataStage
;
; DESCRIPTION: This routine processes the data stage of a control read. It
; must be JUMPed to, not called. It assumes a tranfer descriptor
; has been loaded into the driver myUSB_CurrentTD
; data structure.
;
;-----------------------------------------------------------------------------
myUSB_ControlReadDataStage:
JMP myUSB_LoadEndpoint
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_ControlReadStatusStage
;
; DESCRIPTION: This routine processes the status stage of a control read. It
; must be JUMPed to, not called. It handles short or 0 packet
; It assumes a tranfer descriptor has been loaded into the
; driver myUSB_CurrentTD data structure.
;
;-----------------------------------------------------------------------------
myUSB_ControlReadStatusStage:
MOV A, [myUSB_LastSize] ; Get the number of bytes from the last transfer
ADD [myUSB_TransferByteCount + 1], A ; Update the transfer byte count
ADC [myUSB_TransferByteCount], 0;
MOV A, USB_XFER_STATUS_ACK ; Return a Status ACK Completion
CALL myUSB_UpdateStatusBlock
MOV [myUSB_TransferType], USB_TRANS_STATE_IDLE
MOV A, 0 ; Count Register
MOV X, USB_MODE_STALL_IN_OUT
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_NoDataStageControlTransfer
; myUSB_InitNoDataStageControlTransfer
;
; DESCRIPTION: This routine processes the status stage of a no data control
; write. It must be JUMPed to, not called.
;
;-----------------------------------------------------------------------------
myUSB_NoDataStageControlTransfer:
myUSB_InitNoDataStageControlTransfer:
CALL myUSB_InitializeStatusBlock
MOV [myUSB_TransferType], USB_TRANS_STATE_NO_DATA_CONTROL
MOV A, 0 ; Count Register
MOV X, USB_MODE_STATUS_IN_ONLY
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_InitControlWrite
;
; DESCRIPTION: This routine initializes control write. It must be JUMPed
; to, not called. It assumes a tranfer descriptor has been loaded
; into the driver myUSB_CurrentTD data structure.
;
;-----------------------------------------------------------------------------
myUSB_InitControlWrite:
MOV A, [myUSB_DataSource] ; Need to make sure the destination is not ROM
CMP A, USB_DS_ROM
JZ myUSB_Not_Supported_Local_Drv
CALL myUSB_InitializeStatusBlock
MOV [myUSB_TransferType], USB_TRANS_STATE_CONTROL_WRITE
OR [myUSB_EP0DataToggle], 1 ; setup EP0 data toggle
MOV A, 0 ; Count Register
MOV X, USB_MODE_ACK_OUT_STATUS_IN
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_ControlWriteDataStage
;
; DESCRIPTION: This routine processes the data stage of a control
; write. It must be JUMPed to, not called. It assumes a
; tranfer descriptor has been loaded into the driver
; myUSB_CurrentTD data structure.
;
;-----------------------------------------------------------------------------
myUSB_ControlWriteDataStage:
XOR [myUSB_EP0DataToggle], 1 ; Update data toggle
MOV A,REG[myUSB_EP0CNT] ; Get the count
AND A, 0x0F
SUB A, 2 ; Count include the two byte checksum
MOV [myUSB_t2], A ; Assume we have room to receive the whole packet
MOV A, 0
CMP A, [myUSB_TransferSize] ; If the MSB has anything just use the count
JNZ .L1
MOV A, [myUSB_t2]
CMP A, [myUSB_TransferSize+1] ;
JZ .L6
.L1:
JC .L6
MOV [myUSB_t2], [myUSB_TransferSize+1]
.L6:
MOV A, [myUSB_t2]
SUB [myUSB_TransferSize+1],A ; Update the bytes remaining
SBB [myUSB_TransferSize], 0 ;
ADD [myUSB_TransferByteCount + 1], A ; Update the transfer byte count
ADC [myUSB_TransferByteCount], 0 ;
MOV X,0 ; Start the index at 0
.RAM_COPY:
MOV A, REG[X+myUSB_EP0DATA] ; Get the data
MVI [myUSB_DataPtr+1], A ; Store the data, bump the destination
INC X ; Bump the destination offset
MOV A,X ; Are we done?
CMP A, [myUSB_t2]
JC .RAM_COPY ; Not done
MOV A, 0 ; Count Register
MOV X, USB_MODE_ACK_OUT_STATUS_IN
JMP myUSB_EP0_UPD_MODE_EXIT
; Jump here on data toggle error
.error:
MOV [myUSB_TransferType], USB_TRANS_STATE_IDLE ; This simply aborts the transfer
MOV A, 0 ; Count Register
MOV X, USB_MODE_STALL_IN_OUT
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_ControlWriteStatusStage
;
; DESCRIPTION: This routine processes the status stage of a control
; write. It must be JUMPed to, not called. It assumes a
; tranfer descriptor has been loaded into the driver
; myUSB_CurrentTD data structure.
;
;-----------------------------------------------------------------------------
myUSB_ControlWriteStatusStage:
MOV A, USB_XFER_STATUS_ACK ; Return a Status ACK Completion
CALL myUSB_UpdateStatusBlock
MOV [myUSB_TransferType], USB_TRANS_STATE_IDLE ; The packet is done
MOV A, 0 ; Count Register
MOV X, USB_MODE_STALL_IN_OUT
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_NoDataControlStatusStage
;
; DESCRIPTION: This routine processes the status stage of a control
; write. It must be JUMPed to, not called. It assumes a
; tranfer descriptor has been loaded into the driver
; myUSB_CurrentTD data structure.
;
; USB Device Addressing happens here because we can't change
; the SIE Address before the Status IN is received.
;
;-----------------------------------------------------------------------------
myUSB_NoDataControlStatusStage:
MOV A, USB_XFER_STATUS_ACK ; Return a Status ACK Completion
CALL myUSB_UpdateStatusBlock
; Dispatch to the proper handler
CMP [myUSB_fDataPending], USB_ADDRESS_CHANGE_PENDING
JNZ .L1
; USB ADDRESS CHANGE
MOV A, [myUSB_TransferBuffer] ; Get the pending data
OR A, USB_ADDR_ENABLE ; Set the enable bit
MOV REG[myUSB_ADDR], A ; Update the SIE address
JMP .EXIT
.L1:
.EXIT:
MOV [myUSB_fDataPending], 0 ; Clear data pending
MOV A, 0 ; Count Register
MOV X, USB_MODE_STATUS_IN_ONLY ; Wait for the next SETUP
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_NoDataControlError
;
; DESCRIPTION: This routine handles the condition when we expected a
; status IN, but receive an OUT
;
;-----------------------------------------------------------------------------
myUSB_NoDataControlError:
MOV A, USB_XFER_ERROR ; Return Transaction Error
CALL myUSB_UpdateStatusBlock
MOV A, 0 ; Count Register
MOV X, USB_MODE_STALL_IN_OUT ; Set the mode register
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_LoadEndpoint
;
; DESCRIPTION: Load the endpoint buffer with the next data for the control
; transfer. It assumes a tranfer descriptor has been loaded
; into the driver myUSB_CurrentTD data structure.
;
;-----------------------------------------------------------------------------
myUSB_LoadEndpoint:
MOV A, [myUSB_LastSize] ; Get the number of bytes from the last transfer
ADD [myUSB_TransferByteCount + 1], A ; Update the transfer byte count
ADC [myUSB_TransferByteCount], 0 ;
MOV A, [myUSB_TransferSize] ; Check to see if we have any
OR A, [myUSB_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 [myUSB_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, 0 ; Count Register
MOV [myUSB_LastSize], A ; Clear the byte count
MOV X, USB_MODE_STATUS_OUT_ONLY ; Only ACK the Status Out
JMP myUSB_EP0_UPD_MODE_EXIT
; Jump here to determine how many bytes should we transfer
.cont:
CMP [myUSB_TransferSize], 0 ; Check the MSB
JNZ .L1
CMP [myUSB_TransferSize+1], 8 ; Check the LSB
JNC .L1
MOV A,[myUSB_TransferSize+1] ; Transfer all the remaing data
JMP .L3
.L1:
MOV A, 8 ; Just transfer the next 8 bytes
.L3:
SUB [myUSB_TransferSize+1],A ; Update the bytes remaining
SBB [myUSB_TransferSize],0
MOV [myUSB_t2],A ; Save the count
MOV X,0
CMP [myUSB_DataSource],USB_DS_ROM ; RAM or ROM copy?
JNZ .RAM_COPY
; Copy data from a ROM source
.ROM_COPY:
PUSH X ; Save the destination offset
MOV A,[myUSB_DataPtr] ; Get the transfer source MSB
MOV X,[myUSB_DataPtr+1] ; Set the transfer source LSB
INC [myUSB_DataPtr+1] ; Increment the data pointer
ADC [myUSB_DataPtr], 0 ; MSB if necessary
ROMX ; Get the data byte
POP X ; Get the destination offset
MOV REG[X + myUSB_EP0DATA], A ; Load the data
INC X ; Bump the destination offset
MOV A,X ; Are we done?
CMP A, [myUSB_t2]
JC .ROM_COPY ; Not done
JMP .START_TRANSFER ; Otherwise go start the transfer
; Copy data from a RAM source
.RAM_COPY:
MVI A, [myUSB_DataPtr+1] ; Get the data, bump the source
MOV REG[X +myUSB_EP0DATA], A ; Load the data
INC X ; Bump the destination offset
MOV A,X ; Are we done?
CMP A, [myUSB_t2]
JC .RAM_COPY ; Not done
;; Set up the IN transfer count/mode/etc
; A contains the byte count
.START_TRANSFER:
MOV [myUSB_LastSize], A ; Save the packet size
MOV A, 1
AND A, [myUSB_EP0DataToggle]
JZ .BYPASS_T1
MOV A, USB_CNT_TOGGLE ; Or T1 in the data toggle
.BYPASS_T1:
OR A, [myUSB_LastSize]
XOR [myUSB_EP0DataToggle], 1 ; Update the data toggle for next time
MOV X, USB_MODE_ACK_IN_STATUS_OUT ; Set the mode register
JMP myUSB_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_GetTableEntry
;
; DESCRIPTION: Copies a TD to the myUSB_CurrentTD data structure.
;
;-----------------------------------------------------------------------------
EXPORT myUSB_GetTableEntry
myUSB_GetTableEntry:
INC X ; Point to the first table entry
ADC A, 0 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -