📄 myusb.asm
字号:
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_bGetEPCount
;
; DESCRIPTION:
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
;
; RETURNS:
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.SECTION
myUSB_bGetEPCount:
_myUSB_bGetEPCount:
CMP A, (USB_MAX_EP_NUMBER + 1) ; Range check
JNC .invalid_ep ; Bail out
; Flow here to get the endpoint count
MOV X, A ; Endpoint number is the index
MOV A, REG[X+EP0CNT] ; Here is the count
AND A, 0x1F ; Mask off the count
SUB A, 2 ; Ours includes the two byte checksum
JMP .exit ; Go to the common exit
; Jump here for an invalid endpoint
.invalid_ep:
MOV A, 0 ; Return 0 for an invalid ep
; Jump or flow here for a common exit
.exit:
RET
.ENDSECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_LoadEP
;
; DESCRIPTION: This function loads the specified endpoint buffer
; with the number of bytes previously set in the count
; register.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: A:X Pointer to the ram buffer containing the data to transfer
; myUSB_APIEPNumber loaded with the endpoint number
; myUSB_APICount loaded with the number of bytes to load
;
; RETURNS: NONE
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.SECTION
myUSB_XLoadEP:
_myUSB_XLoadEP:
; extern void myUSB_LoadEP(BYTE, BYTE*);
CMP [myUSB_APIEPNumber], (USB_MAX_EP_NUMBER + 1) ; Range check
JNC .exit ; Bail out
; Flow here to get the endpoint count
MOV [myUSB_APITemp], X ; Use this temp as the MVI pointer
MOV A, [myUSB_APIEPNumber] ; Get the endpoint number
INDEX EPREGPTR ; Get the address of the endpoint data register array
MOV X, A ; We are going to use index access to the register array
MOV A, [myUSB_APICount] ; Get the count
MOV [myUSB_APITemp+1], A ; Use this temp as the count
; Copy loop
.loop:
DEC [myUSB_APITemp+1] ; Are we done?
JC .done ; Jump if we are
MVI A, [myUSB_APITemp] ; Get the data, inc the pointer
MOV REG[X + 0], A ; Store the data
INC X ; Index the next data register
JMP .loop ; Copy the next byte or finish
; Jump here when the copy is finished
.done:
MOV X, [myUSB_APIEPNumber] ; Get the endpoint number
MOV A, X
INDEX myUSB_USB_EP_BIT_LOOKUP
AND A, [myUSB_EPDataToggle]
JZ .addcount
MOV A, USB_CNT_TOGGLE
.addcount:
OR A, [myUSB_APICount] ; Get the count
MOV [X + myUSB_EndpointAPIStatus], NO_EVENT_PENDING ; Set the state
MOV REG[X + EP0CNT], A ; Update the count register
MOV REG[X + EP0MODE], USB_MODE_ACK_IN ; Enable the endpoint
; Jump or flow here for a common exit
.exit:
RET
.LITERAL
EPREGPTR: DB EP0DATA, EP1DATA, EP2DATA
.ENDLITERAL
.ENDSECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_EnableEP
;
; DESCRIPTION: This function enables an OUT endpoint. It should not be
; called for an IN endpoint.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: A contains the endpoint number
;
; RETURNS: None
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.SECTION
myUSB_EnableOutEP:
_myUSB_EnableOutEP:
myUSB_EnableEP:
_myUSB_EnableEP:
CMP A, 0 ; Can't enable EP0
JZ .exit ; Bail out
CMP A, (USB_MAX_EP_NUMBER + 1) ; Range check
JNC .exit ; Bail out
; Flow here to enable an endpoint
MOV X, A ; Endpoint number is the index
MOV [X+myUSB_EndpointAPIStatus], NO_EVENT_PENDING ; For the API
MOV A, REG[X+EP0MODE] ; Unlock the mode register
MOV REG[X+EP0MODE], USB_MODE_ACK_OUT ; Enable the endpoint
; Jump or flow here for a common exit
.exit:
RET ; All done
.ENDSECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_DisableEP
;
; DESCRIPTION: This function disables an OUT endpoint. It should not be
; called for an IN endpoint.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
;
; RETURNS:
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.SECTION
myUSB_DisableOutEP:
_myUSB_DisableOutEP:
myUSB_DisableEP:
_myUSB_DisableEP:
CMP A, 0 ; Can't disable EP0
JZ .exit ; Bail out
CMP A, (USB_MAX_EP_NUMBER + 1) ; Range check
JNC .exit ; Bail out
; Flow here to disable an endpoint
MOV X, A ; Endpoint number is the index
MOV A, REG[X+EP0MODE] ; Unlock the mode register
MOV REG[X+EP0MODE], USB_MODE_NAK_OUT ; Disable the endpoint
; Jump or flow here for a common exit
.exit:
RET ; All done
.ENDSECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_Force
;
; DESCRIPTION: Force the J/K/SE0 State of D+/D-
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: A: USB_FORCE_J
; USB_FORCE_K
; USB_FORCE_SE0
; USB_FORCE_NONE
;
; RETURNS: Nothing
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.SECTION
myUSB_Force:
_myUSB_Force:
CMP A, USB_FORCE_NONE ; Are we done forcing D+/D-?
JZ .none ; Jump if we are done
; Flow here to start checking
CMP A, USB_FORCE_J ; Force J?
JNZ .check_k ; Jump if not J
; Flow here to force J
OR [Port_1_Data_SHADE], 0x02 ; D- = 1
AND [Port_1_Data_SHADE], ~(0x01); D+ = 0
JMP .force ; Go set the force register
; Jump here to check Force K
.check_k:
CMP A, USB_FORCE_K ; Force K?
JNZ .check_se0 ; Jump if not K
; Flow here to force K
OR [Port_1_Data_SHADE], 0x01 ; D+ = 1
AND [Port_1_Data_SHADE], ~(0x02); D- = 0
JMP .force ; Go set the force register
; Jump here to check Force SE0
.check_se0:
CMP A, USB_FORCE_SE0 ; Force SE0?
JZ .invalid ; Jump if not SE0
; Flow here to force SE0
AND [Port_1_Data_SHADE], ~(0x03); D- = 0, D+ = 0
; Jump or flow here to enable forcing (Port bits are set in the shadow register)
.force:
MOV A, [Port_1_Data_SHADE] ; Get the shadow
MOV REG[P1DATA], A ; Update the port
OR REG[USBXCR], USB_FORCE_STATE; Enable FORCING D+/D-
RET ; Exit
; Jump here to clear forcing
.none:
AND REG[USBXCR], ~(USB_FORCE_STATE) ; Disable FORCING D+/D-
; Jump or flow here to exit on end forcing or an invalid parameter
.invalid:
RET ; Exit
.ENDSECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_Suspend
;
; DESCRIPTION: Puts the USB Transceiver into power-down mode, while
; maintaining the USB address assigned by the USB host.
; To restore the USB Transceiver to normal operation, the
; myUSB_Resume function should be called.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: None
;
; RETURNS: Nothing
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.SECTION
myUSB_Suspend:
_myUSB_Suspend:
AND REG[myUSB_ADDR], ~(USB_ADDR_ENABLE) ; Disable transceiver
RET ; Exit
.ENDSECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: myUSB_Resume
;
; DESCRIPTION: Puts the USB Transceiver into normal operation, following
; a call to USB_Suspend. It retains the USB address that had
; been assigned by the USB host.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: None
;
; RETURNS: Nothing
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.SECTION
myUSB_Resume:
_myUSB_Resume:
OR REG[myUSB_ADDR], (USB_ADDR_ENABLE) ; Enable transceiver
RET ; Exit
.ENDSECTION
;-----------------------------------------------
; Add custom application code for routines
;-----------------------------------------------
;@PSoC_UserCode_BODY_1@ (Do not change this line.)
;---------------------------------------------------
; Insert your custom code below this banner
;---------------------------------------------------
;---------------------------------------------------
; Insert your custom code above this banner
;---------------------------------------------------
;@PSoC_UserCode_END@ (Do not change this line.)
; End of File myUSB.asm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -