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

📄 js50.asm

📁 USB大全电子版全部资料3~包含源码、协议等
💻 ASM
📖 第 1 页 / 共 4 页
字号:
      ipret Global_Interrupt  ; enable interrupts and return



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

; The 1 msec interrupt is used to check for suspend and start an

; analog measurement.     

One_mSec_ISR:

	push A                  	; save accumulator on stack

	mov A, [loop_temp]		; Before enumeration end value is zero

	cmp A, 0h

	jz not_main				; Enumeration has not ended 

	dec [loop_temp]			; Enumeration ended decrement counter

not_main:					

; suspend checking

	iord USB_Status_Control		; check if there is no bus activity

	and A, 01h

	cmp A,0h

	jz Inc_counter			; no bus activity

	iord USB_Status_Control		; clear the bus activity bit

	and A, 0FEh

	iowr USB_Status_Control

	mov A, 0h				; clear the suspend counter

	mov [suspend_counter], A

	jmp Suspend_end

Inc_counter:

	inc [suspend_counter]

	mov A, [suspend_counter]	; get idle msec counts

	cmp A, 03h				; check if 3msecs of bus inactivity passed

	jnz Suspend_end			; less than 3msecs

	mov A, 0h				; clear the suspend counter

	mov [suspend_counter], A

	mov A, 0h			; Enable Pullup on port1 lines
	iowr Port1_Pullup
	mov A, 0ffh
	iowr Port1_Data
	iord Status_Control		;set the suspend bit causing suspend

	or A, 08h

	iowr Status_Control	

	nop	
	mov A, 0ffh			; Disable Pullup on port1 lines
	iowr Port1_Pullup
	mov A, 0h
	iowr Port1_Data
	

Suspend_end:

; Starting an analog measurement requires three steps:  

;       1. discharge the timing capacitor

;       2. start charging the timing capacitor

;       3. read and save the start time.

	and A, 0h			; clear carry flag
	mov A, [testbit]        	; select analog channel for measurement

	rrc A

	jnz storeBit



	iord USB_EP1_TX_Config

	cmp A,0                 	; test whether endpoint enabled

	jz Select

	mov A, [start_send]

	cmp A, 01h

	jnz Select

; Check if values have changed

 	mov A, [X_Value_old]

	cmp A, [X_Value]

	jnz send_value

 	mov A, [Y_Value_old]

	cmp A, [Y_Value]

	jnz send_value

 	mov A, [Z_Value_old]

	cmp A, [Z_Value]

	jnz send_value

	mov A, [hat_bits_old]

	cmp A, [hat_bits]

	jnz send_value

	mov A, [button_bits_old]

	cmp A, [button_bits]

	jnz send_value

	mov A, [Throttle_old]

	cmp A, [Throttle]

	jnz send_value

	jmp Select

send_value:

	iord USB_EP1_TX_Config

	and A,40h               	; keep the Data 0/1 bit

	or A,96h                	; enable transmit 6 bytes

	iowr USB_EP1_TX_Config



; Save transmitted values as old values

 	mov A, [X_Value]

	mov [X_Value_old], A

 	mov A, [Y_Value]

	mov [Y_Value_old], A

 	mov A, [Z_Value]

	mov [Z_Value_old], A

	mov A, [hat_bits]

	mov [hat_bits_old], A

	mov A, [button_bits]

	mov [button_bits_old], A

	mov A, [Throttle]

	mov [Throttle_old], A



Select:

	mov A,8				; select fourth channel



storeBit:

	mov [testbit],A         	; start charge cycle

	iowr Port1_Data



; The initial assumption is the start time will always be zero, since

; the measurement is synced with the one millisecond interrupt.  The

; problem with that assumption is there could be a delay due to a USB

; ISR before this interrupt is recognized.



	iord Timer              	; read free-running timer

	mov [start_time],A      	; save start value



	mov A,[interrupt_mask]		; prevent endpoint_1 interrupts

	and A, EFh				; preventing jitter

	mov [interrupt_mask],A	



       ipret Global_Interrupt  	; enable interrupts and return



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

; The GPIO interrupt will be the end of an analog measurement on one

; of the four analog input channels in Port 1.  Complete the measurement

; as a time critical problem, then setup for the next measurement.



GPIO_ISR:

	push A                  ; save the accumulator to stack

	push X                  ; save X on stack

	iord Timer              ; read timer

	push A                  ; save stop time value

	mov A,0                 ; discharge timing capacitor

	iowr Port1_Data



; We need to convert from a bit map to an index that allows us to store

; the result:

;       0001    => 000 X 

;       0010    => 001 Y

;       0100    => 101 Throttle

;       1000    => 010 Z



	mov X,0                 ; clear counter

	mov A,[testbit]         ; load bit under test



	rrc A                   ; test X value

	jc done                 ; index=0 for X value



	inc X

	rrc A                   ; test Y value

	jc done                 ; index=1 for Y value



	mov X,5

	rrc A                   ; test Throttle         

	jc done                 ; index=5 for Throttle



	mov X,2                 ; index=2 for Z value

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

;			Jitter minimization subroutine

; In this subroutine the value of the joystick movement is being

; calculated and the jitter is being minimized by reducing the 

; precision by 2 bits.

done:

	pop A                   ; restore stop time value

	sub A,[start_time]      ; calculate the difference

	mov [jitter_temp],A

	mov A, [X+endpoint_1]	; get previous value

	cmp A, [jitter_temp]	; compare previous to current value

	jc next_minus_prev

	sub A, [jitter_temp]	; previous > current

	jmp check_diff

next_minus_prev:

	mov A, [jitter_temp]	; current > previous

	sub A, [X+endpoint_1]

check_diff:

	cmp A, 4h			; check difference 

	jnc nojitter

	mov A, [X+endpoint_1]	; send previous value

	mov [jitter_temp],A

nojitter:

	mov A, [jitter_temp]	; send current value

	mov [X+endpoint_1],A    ; store the measurement

	pop X                   ; restore X from stack



	mov A, [interrupt_mask] ; enable enpoint_1 interrupts

	or A, 10h			

	mov [interrupt_mask],A	



      ipret Global_Interrupt  ; enable interrupts and return



;********************** Endpoint_1_ISR **************************



USB_EP1_ISR:

	push A          		; save accumulator on stack



	iord USB_EP1_TX_Config  

	xor A,40h               ; flip data 0/1 bit

	iowr USB_EP1_TX_Config



	mov A, [interrupt_mask]

      ipret Global_Interrupt  ; enable interrupts and return



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

; 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. 

Reset:

	mov A, endpoint_0               ; move data stack pointer

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



	mov A, 0ffh                     ; load accumulator with ones



	iowr Port0_Data                 ; output ones to port 0

	iowr Port1_Pullup               ; disable port 1 pullups

						  ; select rising edge interrupts

	iowr Port1_Isink0               ; maximum isink current Port1 bit 0

	iowr Port1_Isink1               ; maximum isink current Port1 bit 1

	iowr Port1_Isink2               ; maximum isink current Port1 bit 2

	iowr Port1_Isink3               ; maximum isink current Port1 bit 3



	mov A, 0h                       ; load accumulator with zeros



	iowr Port1_Data                 ; output zeros to port 1

	iowr Port0_Interrupt            ; disable port 0 interrupts

	iowr Port0_Pullup               ; enable port 0 pullups

	iowr Port0_Isink0               ; minimum sink current Port0 bit 0

	iowr Port0_Isink1               ; minimum sink current Port0 bit 1

	iowr Port0_Isink2               ; minimum sink current Port0 bit 2

	iowr Port0_Isink3               ; minimum sink current Port0 bit 3

	iowr Port0_Isink4               ; minimum sink current Port0 bit 4

	iowr Port0_Isink5               ; minimum sink current Port0 bit 5

	iowr Port0_Isink6               ; minimum sink current Port0 bit 6

	iowr Port0_Isink7               ; minimum sink current Port0 bit 7



	mov [hat_bits],A                ; clear remembered hat bits



	mov A, 80h                      ; default the analog channels

	mov [X_Value],A                 ; X axis

	mov [Y_Value],A                 ; Y axis

	mov [Z_Value],A                 ; Z axis (rotation)

	mov [Throttle],A                ; throttle



	mov A,8                         ; initialize analog channel

	mov [testbit],A                 ; select channel four



	mov A, 0h

	mov [endpoint_stall], A

	mov [remote_wakeup_status], A

	mov [configuration_status], A

	mov [loop_temp], A

	mov [start_send], A

	mov [X_Value_old], A

	mov [Y_Value_old], A

	mov [Z_Value_old], A

	mov [hat_bits_old], A

	mov [button_bits_old], A

	mov [Throttle_old], A



	iowr Watchdog                   ; clear watchdog timer



	mov A, 0fh

	iowr Port1_Interrupt            ; enable port 1 interrupts

;

; 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

;

; A bus 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

	iowr Watchdog           	; clear watchdog timer		

	jz wait	



	mov A, 0ffh				; initializes loop temp

	mov [loop_temp], A

; loop_temp is used to add a delay in the start of transmission of data

; The delay will start after reaching this point.  This means that the 

; transmission of data from endpoint 1 will not start right after enumeration

; is complete but is going to be delayed.  Until the transmission begins 

; the controller will Nak any IN packets to endpoint 1.  If data exists 

; the first IN packet to enpoint 1 that will be responded to with data 

; from the controller is after 230msec from enumeration end.

; This was done to solve driver problems when the joystick was plugged in and

; then the power was recycled or when the joystick was plugged in before the host 

; was turned on.  The joystick driver could not handle the data right after

; enumeration.

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

; This is the main loop that endlessly repeats the same sequence over

; and over.



main:

	mov A, [loop_temp]

	cmp A, 0Ah

	jnc no_set				; do not enable TX yet

	mov A, 01h				; enable transmission

	mov [start_send], A		; after this loop_temp value doesn't matter

no_set:	

	iowr Watchdog           	; clear watchdog timer
	iord Port0_Data                 ; read Port 0

	cpl A                           ; invert the buttons



	push A                          ; save A on stack

	and A,BUTTON_MASK               ; mask button bits

	mov [button_bits], A            ; save the button status

	pop A					  ; restore A from stack



	and A,HAT_MASK

	jz storeHat                     ; no hat button pressed

	mov [temp],A



Test1st:

	and A,10h                       ; test first button

	jz Test2nd                      

	mov A,[temp]

	and A,0E0h                      ; test for multiple buttons

	jnz nochange                    ; hold current state

	mov A,FORWARD                   ; "forward" button is pressed

	jmp storeHat



Test2nd:

	mov A,[temp]

	and A,20h                       ; test second button

	jz Test3rd

	mov A,[temp]

	and A,0D0h                      ; test for multiple buttons

	jnz nochange                    ; hold current state

	mov A,RIGHT                     ; "right" button is pressed

	jmp storeHat



Test3rd:

	mov A,[temp]

	and A,40h                       ; test third button

	jz Test4th

	mov A,[temp]

	and A,0B0h                      ; test for multiple buttons

	jnz nochange                    ; hold current state

	mov A,BACK                      ; "back" button is pressed

	jmp storeHat



Test4th:

	mov A,[temp]

	and A,80h                       ; test fourth button

	jz storeHat                     ; should never happen

	mov A,[temp]

	and A,070h                      ; test for multiple buttons

	jnz nochange                    ; hold current state

	mov A,LEFT                      ; "left" button is pressed



⌨️ 快捷键说明

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