?? ezint.a51
字號:
; This module contains all the EZUSB-specific hardware code
; This module also contains all of the interrupt vector declarations and
; the first level interrupt servicing (register save, call subroutine,
; clear interrupt source, restore registers, return)
; Suspend and Resume are handled totally in this module
;
; A Reset sends us to Program space location 0
CSEG AT 0 ; Code space
USING 0 ; Reset forces Register Bank 0
LJMP Reset
;
; The interrupt vector table is also located here
; EZ-USB has two levels of USB interrupts:
; 1-the main level is described in this table (at ORG 43H)
; 2-there are 21 sources of USB interrupts and these are described in USB_ISR
; This means that two levels of acknowledgement and clearing will be required
; LJMP INT0_ISR ; Features not used are commented out
; ORG 0BH
; LJMP Timer0_ISR
; ORG 13H
; LJMP INT1_ISR
; ORG 1BH
; LJMP Timer1_ISR
; ORG 23H
; LJMP UART0_ISR
; ORG 2BH
; LJMP Timer2_ISR
; ORG 33H
; LJMP WakeUp_ISR
; ORG 3BH
; LJMP UART1_ISR
ORG 43H
LJMP USB_ISR ; Auto Vector will replace byte 45H
; ORG 4BH
; LJMP I2C_ISR
; ORG 53H
; LJMP INT4_ISR
; ORG 5BH
; LJMP INT5_ISR
; ORG 63H
; LJMP INT6_ISR
ORG 1200H ; Load above monSIO0.hex
USB_ISR:LJMP SUDAV_ISR
DB 0 ; Pad entries to 4 bytes
LJMP SOF_ISR
DB 0
LJMP SUTOK_ISR
DB 0
LJMP Suspend_ISR
DB 0
LJMP USBReset_ISR
DB 0
LJMP Reserved
DB 0
LJMP EP0In_ISR
DB 0 ; Comment out features not used
;*Jan's code start
;Uncomment everything up to EP2OUT_ISR
LJMP EP0Out_ISR
DB 0
LJMP EP1In_ISR
DB 0
LJMP EP1Out_ISR
DB 0
LJMP EP2In_ISR
DB 0
LJMP EP2Out_ISR
;Jan's code end
; DB 0
; LJMP EP3In_ISR
; DB 0
; LJMP EP3Out_ISR
; DB 0
; LJMP EP4In_ISR
; DB 0
; LJMP EP4Out_ISR
; DB 0
; LJMP EP5In_ISR
; DB 0
; LJMP EP5Out_ISR
; DB 0
; LJMP EP6In_ISR
; DB 0
; LJMP EP6Out_ISR
; DB 0
; LJMP EP7In_ISR
; DB 0
; LJMP EP7Out_ISR
; End of Interrupt Vector tables
; When a feature is used insert the required interrupt processing here
; The example use only used Endpoints 0 and 1 and also SOF for timing
; *Jan's code also uses the Endpoint 2 Out ISR.
Reserved:
INT0_ISR:
Timer0_ISR:
INT1_ISR:
Timer1_ISR:
UART0_ISR:
Timer2_ISR:
UART1_ISR:
I2C_ISR:
INT4_ISR:
INT5_ISR:
INT6_ISR:
SUTOK_ISR:
EP0Out_ISR:
EP1In_ISR:
EP1Out_ISR:
EP2In_ISR:
;EP2Out_ISR: ;*Jan's code uses this interrupt
EP3In_ISR:
EP3Out_ISR:
EP4In_ISR:
EP4Out_ISR:
EP5In_ISR:
EP5Out_ISR:
EP6In_ISR:
EP6Out_ISR:
EP7In_ISR :
EP7Out_ISR:
Not_Used: ; Should not get any of these
RETI
ClearINT2: ; Tell the hardware that we're done
MOV A, EXIF
CLR ACC.4 ; Clear the Interrupt 2 bit
MOV EXIF, A
RET
USBReset_ISR: ; Bus has been Reset, move to DEFAULT state
CLR Configured
CALL ClearINT2
; No need to clear source of interrupt
RETI
Suspend_ISR: ; SIE detected an Idle bus
MOV A, PCON
ORL A, #1
MOV PCON, A ; Go to sleep!
NOP
NOP ; Wake up here due to a USBResume
NOP
CALL ClearINT2
RETI
WakeUp_ISR: ; Not using external WAKEUP in these examples
; So this must be due to a USBResume
CLR EICON.4 ; Clear the wakeup interrupt source
RETI
EP0In_ISR: ; A prepared packet has been read by PC host
MOV A, SaveLength ; Do I have any more data to send?
JZ NoMoreToSend
MOV DPH, SaveDPH ; Retreive descriptor pointer
MOV DPL, SaveDPL
CALL SendNextPieceOfDescriptor
NoMoreToSend:
CALL ClearINT2
MOV A, #00000001b
MOV DPTR, #IN07IRQ
MOVX @DPTR, A ; Clear source of interrupt
RETI
;*Jan's code starts
EP2Out_ISR:
;This version of the code enables the chip to do interrupt Out report transfers.
;Windows 98 SE and later support interrupt Out transfers for HIDs.
;The code is similar to the ProcessOutputReport code used for Get_Report control transfers
; The report is only one byte long in this first example
; It contains a new value for the LEDs
PUSH DPL
PUSH DPH
; PUSH DPL1 ; Uncomment if not using evaluation version
; PUSH DPH1
PUSH ACC
CALL ClearINT2 ; Clear the 8051 USB interrupt
MOV DPTR, #OUT07IRQ ; Clear Endpoint 2 Out's interrupt request bit
MOV A, #00000100b
MOVX @DPTR, A
; MOV DPTR, #OUT2ByteCount ; How many bytes were received?
; MOVX A, @DPTR ; (This example doesn't use the count value)
MOV DPTR, #EP2OutBuffer ; Get the data from the endpoint's buffer
MOVX A, @DPTR
MOV LEDValue, A ; Update the local variable
;Write any value to Endpoint 2's OUT ByteCount register
;to enable receiving new data at Endpoint 2.
MOV DPTR, #OUT2ByteCount ; Store the address of EP2 Out's ByteCount register
MOVX @DPTR, A ; Write any value to the ByteCount register
POP ACC
; POP DPH1 ; Uncomment if not using evaluation version
; POP DPL1
POP DPH
POP DPL
RETI
;*Jan's code ends
SOF_ISR: ; A Start-Of-Frame packet has been received
; CALL ServiceTimerRoutine
; This routine services the real time interrupt
; It is also responsible for the "real world" buttons and lights
;
ServiceTimerRoutine:
DJNZ Msec_counter, Done ; Only need to check every 4msec
MOV Msec_counter, #4 ; Reinitialize
; LED task
MOV A, LEDValue
MOV DPTR, #PortB_Out
MOVX @DPTR, A ; Update the real world
;
; Create an Input Report from the Buttons value
; This will be continually overwritten while the PCHost is not polling for data
ReadButtons:
MOV DPTR, #PortA_Pins
MOVX A, @DPTR
CALL CreateInputReport
Done: CALL ClearINT2
; Clear the source of the interrupt
MOV A, #00000010b
ExitISR:MOV DPTR, #USBIRQ
MOVX @DPTR, A
RETI
SUDAV_ISR: ; A Setup packet has been received
MOV SaveLength, #0 ; Clear any pending transactions (if any)
MOV DPTR, #SETUPDAT ; Copy packet to direct access memory
MOV R0, #SetupData
MOV R7, #8
CopySD: MOVX A, @DPTR
MOV @R0, A
INC DPTR
INC R0
DJNZ R7, CopySD
CALL ServiceSetupPacket ; Handle the decode of the Setup packet
; if SetAddress { Update SIE address } // NOP on EZ-USB
; if STALL { Stall the endpoint }
; if SendData {
; if IsDescriptor { send DPTR->descriptor, A = length }
; else { send ReplyBuffer }
; }
JB STALL, SendSTALL
JNB SendData, HandShake
JB IsDescriptor, LoadEP0
; Send data in ReplyBuffer
MOV DPTR, #EP0InBuffer+1
MOV R0, #ReplyBuffer+1
MOV R7, #2 ; Copy the two byte buffer
CopyRB: MOV A, @R0
MOVX @DPTR, A
DEC DPL
DEC R0
DJNZ R7, CopyRB
MOV A, @R0 ; Get BufferCount
SendEP0InBuffer:
MOV DPTR, #In0ByteCount
StartXfer:
MOVX @DPTR, A ; This write initiates the transfer
HandShake: ; Handshake with host
MOV R7, #00000010b ; Set HSNAK to tell the SIE that we're done
SetEP0Control:
MOV DPTR, #EP0Control
MOVX A, @DPTR
ORL A, R7
MOVX @DPTR, A ; We're done
CALL ClearINT2
MOV A, #00000001b ; Clear the source of the interrupt
JMP ExitISR
SendSTALL: ; Invalid Request was received
MOV R7, #00000011b ; Set EP0STALL and HSNAK
JMP SetEP0Control
LoadEP0: ; Send the data pointed to by DPTR
MOV R7, A ; Save LENGTH
; Need to return the smaller of "Requested Length" and "Actual Length"
; If "Requested Length" > 255 then use "Actual Length"
; There are no descriptors > 255 in this example
MOV A, wLengthHigh
JNZ UseActual
CLR C
SUBB A, wLengthLow
MOV A, wLengthLow ; This does not affect Carry
JNC UsewLengthLow
UseActual:
MOV A, R7
UsewLengthLow:
SendNextPieceOfDescriptor: ; DPTR -> Descriptor to be sent
MOV R7, A ; Save LENGTH again
MOV SaveLength, #0 ; Default case, overwrite if necessary
; Do I have more than a single packet to send?
CLR C
SUBB A, #EP0Size
JC SendPacket
; Need to send multiple packets.
; Calculate and save address of next packet, send next packet now
MOV SaveLength, A ; Send these next time
MOV R7, #EP0Size
PUSH DPH ; Save current pointer
PUSH DPL
MOV A, R7 ; Retreive length
CALL BumpDPTR
MOV SaveDPH, DPH
MOV SaveDPL, DPL
POP DPL
POP DPH
SendPacket:
MOV A, R7 ; Retreive length
MOV R6, A ; Save length in R6 for move
MOV R0, #LOW(EP0InBuffer) ; PageReg = 7FH = HIGH(EP0InBuffer)
CopySTD:MOVX A, @DPTR
MOVX @R0, A
INC DPTR
INC R0
DJNZ R6, CopySTD
MOV A, R7 ; Retrieve LENGTH
JMP SendEP0InBuffer
GetOutputReport: ; Wait for this, it's next on USB
MOV DPTR, #Out0ByteCount ; Enable EP0OutBuffer to receive data
MOVX @DPTR, A ; Any value will do
MOV DPTR, #EP0Control ; Wait for valid data in EP0OutBuffer
Wait40: MOVX A, @DPTR
ANL A, #00001000b ; Check OUTBSY
JNZ Wait40
RET
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -