www.pudn.com > the USB Simple Terminal example (PC Host Software > vectors.a51


; This module is common to all of the examples. 
; It 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	Serial0_ISR 
;	ORG	2BH 
;	LJMP	Timer2_ISR 
;	ORG	33H 
;	LJMP	WakeUp_ISR 
;	ORG	3BH 
;	LJMP	Serial1_ISR	; Used by dScope 
	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	0E0H		; Keep out of the way of dScope monitor 
				; If you are not using dScope then this memory hole 
				; may be used for useful routines. 
	ORG	100H	 
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 
	LJMP	EP0Out_ISR 
	DB	0 
	LJMP	EP1In_ISR 
	DB	0 
; 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 
SUTOK_ISR: 
EP0In_ISR: 
EP0Out_ISR: 
Reserved: 
	RETI			; Should not get these 
 
; Note that MAIN does not use any registers and each interrupt runs to 
; completion (no nesting) so there is no need to save registers 
 
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 
  
SUDAV_ISR:			; A Setup packet has been received 
	CALL	ServiceSetupPacket 
	CALL	ClearINT2				 
	                        ; Clear the source of the interrupt 
	MOV	A, #00000001b 
ExitISR:MOV	DPTR, #USBIRQ 
	MOVX	@DPTR, A 
	RETI 
 
SOF_ISR:			; A Start-Of-Frame packet has been received 
	CALL	ServiceTimerRoutine 
	CALL	ClearINT2				 
	                        ; Clear the source of the interrupt 
	MOV	A, #00000010b 
	JMP	ExitISR 
 
EP1In_ISR:			; EP1 In Buffer has just been read.  
	CALL	ClearINT2	; First clear the source of the interrupt 
	MOV	DPTR, #IN07IRQ 
	MOV	A, #00000010b 
	MOVX	@DPTR, A 
; Create another report if there is a character available 
	MOV	R0, USBout	; Get pointer into circular buffer 
	MOV	A, @R0 
	JNZ	USBCharacterAvailable 
	SETB	EP1INReady	; Set a flag to say that EP1IN is available 
	RETI 
USBCharacterAvailable: 
	CALL	CreateInputReport 
	RETI 
 
Serial0_ISR: 
	MOV	A, S0Control	; Check for TXDone or RXReady 
	JB	ACC.1, TXDone 
RXReady:			; Character just received 
	CLR	S0Control.0	; Clear the Interrupt bit 
	MOV	R0, SerialIN	; Is there room in the Receive Buffer? 
	MOV	A, @R0 
	JZ	OKtoWriteRB 
	SETB	RBFull 
	RETI 
OKtoWriteRB: 
	MOV	A, S0Data	; Get the character 
	MOV	@R0, A		; And put it in the Receive Buffer 
	INC	R0		; Bump the buffer pointer 
	CJNE	R0, #ReceiveBufferEnd, NoWrapRB1 
	MOV	R0, #ReceiveBuffer 
NoWrapRB1: 
	MOV	SerialIN, R0 
; 
; Check to see if USB is waiting for a character 
	JB	EP1INReady, USBCharacterAvailable 
	RETI 
 
TXDone:				; Just finished transmitting a character 
	CLR	S0Control.1	; Clear the Interrupt bit 
	MOV	R0, SerialOUT 
	MOV	A, @R0		; Is another available 
	JNZ	SerialCharacterAvailable 
	SETB	TXReady 
	RETI 
SerialCharacterAvailable: 
        CALL	SendChar 
	RETI 
 
SendChar:			; Send a character to the serial port 
	MOV	R0, SerialOUT 
	MOV	A, @R0 
	MOV	S0Data, A 
	CLR	A 
	MOV	@R0, A		; Clear the character entry just sent 
	INC	R0 
	CJNE	R0, #SendBufferEnd, NoWrapSB1 
	MOV	R0, #SendBuffer 
NoWrapSB1: 
	MOV	SerialOUT, R0 
        CLR	TXReady 
	RET 
 
; ProcessOutputReport and CreateInputReport moved into Vectors module so 
; that filling/emptying the Send/Receive buffers was in one place 
 
ProcessOutputReport:		  	; A Report has just been received 
; The report contains a character to be sent to the Serial port 
; Save the character in the Send circular buffer 
	MOV	DPTR, #EP0OutBuffer	; Point to the Report 
	MOV	R0, USBin		; Point into the Send Buffer 
	MOV	A, @R0			; Get the entry in the Send Buffer 
	JZ	OKtoWriteSB		; Check that it's empty 
	SETB	SBFull			; Set an error bit 
	RET				; Throw away the newest characters! 
OKtoWriteSB: 
	MOVX	A, @DPTR		; Get the character 
	MOV	@R0, A			; Write to the Send Buffer 
	INC	R0			; Bump the buffer pointer 
	CJNE	R0, #SendBufferEnd, NoWrapSB2 
	MOV	R0, #SendBuffer		; Maintain a circular buffer 
NoWrapSB2: 
	MOV	USBin, R0		; Save IN pointer 
; 
; Check to see if the Serial port is waiting for a character 
	JB	TXReady, SendChar 
	RET 
 
CreateInputReport: 
; The report contains a character from the serial port 
; Get the character from the Receive circular buffer 
	MOV	DPTR, #EP1InBuffer	; Point to the buffer 
	MOV	R0, USBout		; Point into the Receive Buffer 
	MOV	A, @R0			; Get character from Receive Buffer 
	MOVX	@DPTR, A		;        and update the Report 
	CLR	A 
	MOV	@R0, A			; Clear the Receive Buffer entry just read 
	INC	R0 
	CJNE	R0, #ReceiveBufferEnd, NoWrapRB2 
	MOV	R0, #ReceiveBuffer	; Maintain a circular buffer 
NoWrapRB2: 
	MOV	USBout, R0		; Save OUT pointer	  
	MOV	DPTR, #IN1ByteCount 
	MOV	A, #1 
	MOVX	@DPTR, A		; Endpoint 1 now 'armed', next IN will get data 
	CLR	EP1INReady 
	RET