⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mouse45b.asm

📁 USB大全电子版全部资料3~包含源码、协议等
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	push A

	mov A, 0h					; clear Cext ( Discharge Capacitor )

	iowr Cext

	mov A, 0f0h					; turn on the phototransistors

	iowr Port0_Data			

	mov A, 0feh             		; turn on the LED on Port 1 bit[0]

	iowr Port1_Data

	mov A, FFh

	mov [disch_counter], A

delay2:

	dec A

	jnz delay2

	iowr Watchdog				; clear watchdog timer

	mov A, FFh

	dec [disch_counter]

	jnz delay2



	iord Port0_Data				; read port 0

	cmp A, [port_temp]			; compare port 0 data to previosly stored data

	jz No_change

	iord USB_Status_Control			; check if there is no bus activity

	and A, BusActivity

	jnz Wakeup_end				; bus active

	iord USB_Status_Control			; set J state

	or A, 04h					; 

	iowr USB_Status_Control

	and A, 0fBh					; clear J state

	iowr USB_Status_Control

	iord USB_Status_Control			; send wakeup to host

	or A, ForceResume				; set Force Resume bit

	iowr USB_Status_Control

	mov A, 01h					; set wakeup flag

	mov [wakeup_flag], A

	mov A, 0h					; clear wakeup counter

	mov [wakeup_counter], A

	mov A, TIMER_ONLY				; enable one msec timer interrupts

	iowr Global_Interrupt

Wakeup_wait:

	mov A, [wakeup_counter]			; Wait for 10ms

	cmp A, 0Ah

	jc Wakeup_wait

	mov A, 0h					; disable interrupts

	iowr Global_Interrupt		

	iord USB_Status_Control			; Clear Force Resume bit 

	and A, ~ForceResume					

	iowr USB_Status_Control

	mov A, 0h					; clear wakeup flag

	mov [wakeup_flag], A

	iord Port0_Data				; read port 0

	mov [port_temp], A			; save value

No_change:

      mov A, 0ffh             		; turn off the LED on Port 1 bit[0]

	iowr Port1_Data	

	mov A, 01h					; disable open drain O/P driver

	iowr Cext					; start charging for the next one

Wakeup_end:

	mov A, WAKEUP_MASK

	ipret Global_Interrupt



;*******************************************************

; The 1 msec interrupt is only used to clear the watchdog 

; timer.  This interrupt service routine would be the

; place to enter suspend mode.

One_mSec_ISR:

	push A

	iowr Watchdog				; clear watchdog timer

 

	dec [4ms_counter]                   ; count til 4 to increment

      jnz button_debounce

      mov A,[idle_period_counter]

      cmp A, 0ffh                         ; if 0ffH is reach in the 

      jz 4ms_set                          ; idle_period_counter no more

      inc [idle_period_counter]           ; increment

4ms_set:

      mov A,4

      mov [4ms_counter],A



button_debounce:

	mov A, [button1_deb]

	cmp A, 0h

	jz no_debounce

	inc A

	mov [button1_deb], A

	cmp A, 30

	jnz no_debounce

	mov A, 0h

	mov [button1_deb], A	

no_debounce:

	mov A, [wakeup_flag]			; check if we are in a remote wakeup process

	cmp A, 01h

	jnz notremote_wakeup

	inc [wakeup_counter]			; increment wakeup counter

	mov A, TIMER_ONLY				; enable One_msec_ISR

	ipret Global_Interrupt

notremote_wakeup:

	iord USB_Status_Control			; check if there is no bus activity

	and A, BusActivity

	jz Inc_counter				; no bus activity

	iord USB_Status_Control			; clear the bus activity bit

	and A, ~BusActivity

	iowr USB_Status_Control

	mov A, 3h					; clear the suspend counter

	mov [suspend_counter], A

	jmp One_mSec_end

Inc_counter:

	dec [suspend_counter]			; check if 3msecs of bus inactivity passed

	jnz One_mSec_end				; less than 3msecs

	iord Port0_Data				; save current value

	mov [port_temp], A



	mov A, 3h					; clear the suspend counter

	mov [suspend_counter], A

      mov A, 0ffh             		; turn off the LED on Port 1 bit[0]

	iowr Port1_Data

	iowr Port0_Data

	mov A, [remote_wakeup_status]		; check if remote wakeup is enabled 

	cmp A, ENABLE_REMOTE_WAKEUP

	jnz Suspend1				; Not enabled

	

	mov A, 0

	iowr Cext

	mov A, FFh

	mov [disch_counter], A

delay:

	dec A

	jnz delay

	iowr Watchdog				; clear watchdog timer

	mov A, FFh

	dec [disch_counter]

	jnz delay



	mov A, 01h					

	iowr Cext					; start charging external capacitor

	mov A, WAKEUP_MASK			; wakeup is the ONLY interrupt enabled

	iowr Global_Interrupt

Suspend1:

	iord Status_Control			;set the suspend bit causing suspend

	or A, SuspendBits

	iowr Status_Control

	nop

	mov A, 0f0h					; turn on the phototransistors

	iowr Port0_Data	

	mov A, 0feh             		; turn on the LED on Port 1 bit[0]

	iowr Port1_Data	

One_mSec_end:

	mov A, [interrupt_mask]

	ipret Global_Interrupt



;*******************************************************

;	Interrupt handler: endpoint_one

;	Purpose: This interrupt routine handles the specially

;		 reserved data endpoint 1 (for a mouse).  This

;		 interrupt happens every time a host sends an

;		 IN on endpoint 1.  The data to send (NAK or 3

;		 byte packet) is already loaded, so this routine

;		 just prepares the dma buffers for the next packet

USB_EP1_ISR:

	push A				; save accumulator on stack



	iord USB_EP1_TX_Config		; return NAK when data is not

	and A, 7Fh				; ready

	xor A, DataToggle			; flip data 0/1 bit

	iowr USB_EP1_TX_Config



	mov A, 0h

	mov [horiz_position], A	

	mov [vert_position], A	

	mov [button_position], A	



	mov A, [interrupt_mask]		; return from interrupt

	ipret Global_Interrupt



;*******************************************************

; reset processing

; The idea is to put the microcontroller in a known state.  As this

; is the entry point for the "reserved" interrupt vector, we may not

; assume the processor has actually been reset and must write to all

; of the I/O ports.

;

;	Port 0 bits 3:0 are the phototransistors

;		Write these pins "low" with midrange current to bias 

;		the phototransistors.

;	Port 0 bits 7:4 are the mouse buttons

;		Write these pins "high" with pullup resistors to 

;		support the mouse buttons.

;	Port 1 bit 0 is the LED output

;		Write this pin low with maximum current sink to turn

;		on the LEDs.

Reset:

	mov A, endpoint_0	; move data stack pointer

	swap A, dsp		; so it does not write over USB fifos

;

; initialize Port 0

;

	mov A, Ptr_Current		; select midrange DAC setting

	iowr Port0_Isink0			; isink current Port 0 bit[0]

	iowr Port0_Isink1			; isink current Port 0 bit[1]

	iowr Port0_Isink2			; isink current Port 0 bit[2]

	iowr Port0_Isink3			; isink current Port 0 bit[3]



	mov A, 0				; select minimum DAC setting

	iowr Port0_Isink4			; isink current Port 0 bit[4]

	iowr Port0_Isink5			; isink current Port 0 bit[5]

	iowr Port0_Isink6			; isink current Port 0 bit[6]

	iowr Port0_Isink7			; isink current Port 0 bit[7]



	mov A, 0fh				; disable Port 0 bit[3:0] pullups

	iowr Port0_Pullup			; enable  Port 0 bit[7:4] pullups



	mov A, 0f0h				; initialize Port 0 data

	iowr Port0_Data			; output zeros to Port 0 bit[3:0]

						; output ones  to Port 0 bit[7:4]

	mov [port_temp], A



;

; initialize Port 1

;

	mov A, LED_Current		; select maximum DAC setting

	iowr Port1_Isink0			; isink current Port 1 bit[0]

	iowr Port1_Isink1			; isink current Port 1 bit[1]

	iowr Port1_Isink2			; isink current Port 1 bit[2]

	iowr Port1_Isink3			; isink current Port 1 bit[3]



	mov A, 0h				; enable Port 1 bit [7:0] pullups

	iowr Port1_Pullup	

	

      mov A, 0feh             	; turn on the LED on Port 1 bit[0]

	iowr Port1_Data	



	mov A, 0		

	iowr Port0_Interrupt		; disable port 0 interrupts  

	iowr Port1_Interrupt		; disable port 1 interrupts

	iowr Cext

;

; initialize variables

;

	mov [buttons], A			; no buttons pushed

	mov [horiz_state], A		; clear the horizontal state

	mov [horizontal], A		; clear horizontal count

	mov [vert_state], A		; clear the vertical state

	mov [vertical], A			; clear vertical count

	mov [endpoint_stall], A

	mov [remote_wakeup_status], A

	mov [configuration_status], A

	mov [wakeup_counter], A

	mov [wakeup_flag], A

	mov [disch_counter], A

	mov [horiz_position], A

	mov [vert_position], A

	mov [button_position], A

	mov [button_flag], A

	mov [button1_deb], A

      mov [idle_period], A

      mov [prev_idle_period], A

	mov [new_idle_period], A

	mov [new_idle_flag], A

      mov [idle_period_counter], A

	mov A,3				; initialize suspend counter

	mov [suspend_counter], A	; 3 msec idle, suspend



      mov A,4				; initialize  4ms_counter to 4

	mov [4ms_counter], A     	; 



	iowr Watchdog			; clear watchdog timer

;	mov A, ENABLE_REMOTE_WAKEUP	; **** debug only ****

;	mov [remote_wakeup_status], A



	mov A, BOOT_PROTOCOL

	mov [protocol_status], A



;

; test what kind of reset occurred 

;

	iord Status_Control

	and A, USBReset			; test for USB Bus Reset

	jnz BusReset



	iord Status_Control

	and A, WatchDogReset		; test for Watch Dog Reset

	jz suspendReset

;

; Process a watchdog reset.  Wait for a Bus Reset to bring the system

; alive again.



	mov A, TIMER_ONLY			; enable one msec timer interrupt

	mov [interrupt_mask],A

	iowr Global_Interrupt



WatchdogHandler:				; wait for USB Bus Reset

	jmp WatchdogHandler

suspendReset:

	mov A, 09h

	iowr Status_Control		; go back to suspend

	nop

	jmp suspendReset			; wait until real bus reset

;

; Either a bus reset or a normal reset has occurred

;

BusReset:

	mov A, RunBit			; clear all reset bits

	iowr Status_Control



; setup for enumeration

	mov A, ENUMERATE_MASK	

	mov [interrupt_mask],A

	iowr Global_Interrupt



wait:				; wait until configured

	iord USB_EP1_TX_Config

	cmp A, 0		

	jz wait	



;*******************************************************

; main loop 

;	Purpose: This routine is the code for implementing

;		 a mouse function.  It is divided into three

;		 parts; buttons, horizontal movement, and

;		 vertical movement.  See the documentation

;		 for an explanation of the movement

;		 state machines.

;

;*******************************************************

main:

	iord Port0_Data		; read and store port 0

	mov [port_temp], A

	call ReadButtons		; read the buttons

	call CheckHorizontal	; check for horizontal movement

	call CheckVertical	; check for vertical movement



     

      mov A, [horizontal]	

	cmp A, 0h

	jz NoChangeHorizontal

      jmp send_packet

NoChangeHorizontal:

	mov A, [vertical]	

	cmp A, 0h

	jz NoChangeVertical

      jmp send_packet             

NoChangeVertical:

	mov A, [button_flag]	

	cmp A, 0h

	jz NoChangeButtons

	jnz send_packet

NoChangeButtons:                              

      mov A, [idle_period]                    ;if idle period is 0

      cmp A, 0h                               ;report is sent only if changes 

      jz Nosend



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -