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

📄 mouse.asm

📁 Cypress USB HID code
💻 ASM
📖 第 1 页 / 共 5 页
字号:

		;*******************
		;
		;	optic Y1
		;
		;*******************

		measure_y1_optics:
		
		;***** optic Y1 - pulse and release
		mov		A, LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON | X0 | X1 | Y0
		iowr	Y_OPTICS_PORT


		;***** release optic into hi-z mode
		mov		A, 00h						; clear gpio interrupt flag
		mov		[gpio_int_flag], A
		mov		A, Y1						; enable gpio interrupt
		iowr	port0_int
		mov		A, 80h | X0 | X1 | Y0		; set pin in hi-z mode
		iowr	port0_mode0 


		;***** measure rise time
		mov		A, 00h						; clear interrupt flag
		mov		[int_flag], A
		iord	timer_lsb					; store the start timer
		mov		[optic_start_time], A
		mov		A, 00h

		wait_timer_y1:						; wait for gpio interrupt to occur
			cmp		A, [gpio_int_flag]
			jz		wait_timer_y1

		mov		X, [int_flag]				; store the int_flag in X

		;***** restore Y1 port to medium - drive 1 strength
		mov		A, 00h						; disable gpio interrupt
		iowr	port0_int
		mov		A, LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON | X0 | X1 | Y0 | Y1
		iowr	Y_OPTICS_PORT
		mov		A, 80h | X0 | X1 | Y0 | Y1
		iowr	port0_mode0		

		;***** check if interrupt went off during measurement
		;***** this could possibly corrupt the timing measurement
		;***** so we have to ignore the measured data if this happens
		mov		A, X		
		cmp		A, 00h
		jz		y1_no_interrupt_went_off
		y1_interrupt_went_off:
			mov		A, [y_last_state]
			mov		[y_current_state], A
			jmp		analyze_x_optics

		y1_no_interrupt_went_off:
			mov		A, [optic_finish_time]	; get the finish time
			sub		A, [optic_start_time]	; get time difference
			push	A						; stash time difference away

		;***** if time differnce is greater than max time, store this as 
		;***** the new max time and recalculate the average time
		compare_y1_max:
			cmp		A, [y1_max_time]
			jc		compare_y1_min
			cmp		A, THRESHOLD_TIME		; guard band in case we hit an
			jnc		compare_y1_min			; interrupt during timer measurement

			; set new max time
			mov		[y1_max_time], A	
			; recalculate average
			add		A, [y1_min_time]
			jc		calc_y1_xavg_with_carry
				calc_y1_xavg_without_carry:
					asr		A		; divide value by 2
					mov		[y1_avg_time], A				
					jmp		calc_y1_xavg_hysteresis

				calc_y1_xavg_with_carry:
					asr		A
					or		A, 80h				; add msb back in to average
					mov		[y1_avg_time], A
					
				calc_y1_xavg_hysteresis:
					mov		A, [y1_max_time]	; hysteresis high value
					sub		A, [y1_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [y1_avg_time]
					mov		[y1_hyst_high], A

					mov		A, [y1_avg_time]	; hysteresis low value
					sub		A, [y1_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [y1_avg_time]
					sub		A, [temp]
					mov		[y1_hyst_low], A
					

		; if time differnce is less than max time, store this as 
		; the new max time and recalculate the average time
		compare_y1_min:
			pop		A
			push	A
			cmp		A, [y1_min_time]
			jnc		compare_y1_avg
			; set new min time
			mov		[y1_min_time], A
			; recalculate average
			add		A, [y1_max_time]
			jc		calc_y1_mavg_with_carry
				calc_y1_mavg_without_carry:
					asr		A		; divide value by 2
					mov		[y1_avg_time], A
					jmp		calc_y1_mavg_hysteresis

				calc_y1_mavg_with_carry:
					asr		A
					or		A, 80h	; add msb back in to average
					mov		[y1_avg_time], A

				calc_y1_mavg_hysteresis:
					mov		A, [y1_max_time]	; hysteresis high value
					sub		A, [y1_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [y1_avg_time]
					mov		[y1_hyst_high], A

					mov		A, [y1_avg_time]	; hysteresis low value
					sub		A, [y1_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [y1_avg_time]
					sub		A, [temp]
					mov		[y1_hyst_low], A


		; compare the timer value to the average value to determine if
		; the output value was a 1 or 0
		compare_y1_avg:
			pop		A						; get last measured time
			cmp		A, [y1_hyst_low]
			jc		y1_is_zero
			cmp		A, [y1_hyst_high]
			jnc		y1_is_one

			y1_invalid:
				mov		A, [y_last_state]
				and		A, 02h
				or		[y_current_state], A
				jmp		analyze_x_optics

			y1_is_one:
				mov		A, 02h
				or		[y_current_state], A

			y1_is_zero:



		;**************************************************
		;***** analyze optic values to determine quadrature
		;***** movement - if any

		analyze_x_optics:
			mov		A, [x_last_state]
			asl		A
			asl		A
			or		A, [x_current_state]
			asl		A
			jacc	x_jumptable				; jump to transition state

			x_increment:
				mov		A, [x_current_state]
				mov		[x_last_state], A
				inc		[ep1_dmabuff1]		; increment mouse cursor change	
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
				jmp		analyze_y_optics					
			x_decrement:
				mov		A, [x_current_state]
				mov		[x_last_state], A
				dec		[ep1_dmabuff1]		; decrement mouse cursor change
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
				jmp		analyze_y_optics
			x_error:

 		analyze_y_optics:
			mov		A, [y_last_state]
			asl		A
			asl		A
			or		A, [y_current_state]
			asl		A
			jacc	y_jumptable				; jump to transition state

			y_increment:
 				mov		A, [y_current_state]
				mov		[y_last_state], A
				inc		[ep1_dmabuff2]		; increment mouse cursor change	
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
				jmp		analyze_z_optics					
			y_decrement:
 				mov		A, [y_current_state]
				mov		[y_last_state], A
				dec		[ep1_dmabuff2]		; decrement mouse cursor change
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
				jmp		analyze_z_optics
			y_error:

		analyze_z_optics:
;			mov		A, [z_last_state]
;			asl		A
;			asl		A
;			or		A, [z_current_state]
;			asl		A
;			jacc	z_jumptable				; jump to transition state
;
			z_forward:
;				mov		A, 01h
;				mov		[ep1_dmabuff3], A	; increment mouse wheel change	
;				mov		A, EVENT_PENDING	; set event pending to signal data to
;				mov		[event_machine], A	; send to the host
;				jmp		optic_task_done					
			z_backward:
;				mov		A, FFh
;				mov		[ep1_dmabuff3], A	; decrement mouse wheel change
;				mov		A, EVENT_PENDING	; set event pending to signal data to
;				mov		[event_machine], A	; send to the host
	
	optic_task_done:
;		mov		A, [z_current_state]
;		mov		[z_last_state], A
	
; this task sends data out endpoint 1 if the endpoint is configured
; and not set to stall

	mov		A, [event_machine]
	jacc	event_machine_jumptable
		event_pending:
			; if not configured then skip data transfer
			mov		A, [configuration]
			cmp		A, 01h
			jnz		event_task_done
			; if stalled then skip data transfer
			mov		A, [ep1_stall]
			cmp		A, FFh
			jz		event_task_done
			
			; We have to determine which protocol is currently enabled
			; and send the format that is supported by that protocol
			mov		A, [protocol]
			cmp		A, HID_REPORT
			jnz		boot_protocol_report

		hid_protocol_report:
			mov		A, 04h					; set endpoint 1 to send 3 bytes
			or		A, [ep1_data_toggle]
			iowr	ep1_count
			mov		A, ACK_IN				; set to ack on endpoint 1
			iowr	ep1_mode	
			jmp		event_task_done

		boot_protocol_report:
			mov		A, 03h					; set endpoint 1 to send 3 bytes
			or		A, [ep1_data_toggle]
			iowr	ep1_count
			mov		A, ACK_IN				; set to ack on endpoint 1
			iowr	ep1_mode	


		event_task_done:
			mov		A, NO_EVENT_PENDING		; clear pending events
			mov		[event_machine], A 
		no_event_task:


	jmp task_loop

;*******************************************************
;
;	Interrupt handler: gpio
;	Purpose: The program jumps to this routine when
;			a gpio interrupt occurs.
;
;*******************************************************

gpio:
	push	A
	
	iord	timer_lsb					; store current timer value
	mov		[optic_finish_time], A
;	mov		A, 01h
;	mov		[gpio_int_flag], A			; set a flag to indicate
	inc		[gpio_int_flag]
										; that a gpio interrupt occurred
	pop		A
	reti


;*******************************************************
;
;	Interrupt handler: Bus_reset
;	Purpose: The program jumps to this routine when
;		 the host causes a USB reset.
;
;*******************************************************

Bus_reset:

	mov		A, STALL_IN_OUT					; set to STALL INs&OUTs
	iowr	ep0_mode

	mov		A, ADDRESS_ENABLE				; enable USB address 0
	iowr	usb_address
	mov		A, DISABLE						; disable endpoint1
	iowr	ep1_mode

	mov		A, 00h							; reset program stack pointer
	mov		psp,a	

	jmp		Main


;*******************************************************
;
;	Interrupt: 1ms_clear_control
;	Purpose: This interrupt handler sets a flag to indicate
;		it's time to read the buttons in the main task loop,
;		watches for USB suspend, and handles the HID idle
;		timer.
;
;*******************************************************

1ms_timer:
	push A

	; flag that interrupt went off during processing.
	inc		[int_flag]

	;**********************************
	; poll buttons for button on/off state

	mov		A, [button_machine]
	cmp		A, BUTTON_DATA_PENDING
	jz		1ms_suspend_timer
	
		; if the main task has read the buttons, then we need to re-read the 
		; buttons and set the pending flag

		mov		A, 00h
		mov		[current_button_state], A
	left_button_read:
		iord	LEFT_BUTTON_PORT
		and		A, LEFT_BUTTON
		jnz		right_button_read
			mov		A, HID_LEFT_MOUSE_BUTTON
			or		[current_button_state], A
	right_button_read:
		iord	RIGHT_BUTTON_PORT
		and		A, RIGHT_BUTTON
		jnz		middle_button_read
			mov		A, HID_RIGHT_MOUSE_BUTTON 
			or		[current_button_state], A
	middle_button_read:
		iord	MIDDLE_BUTTON_PORT
		and		A, MIDDLE_BUTTON
		jnz		button_read_done
			mov		A, HID_MIDDLE_MOUSE_BUTTON
			or		[current_button_state], A
	button_read_done:
  		mov		A, BUTTON_DATA_PENDING
		mov		[button_machine], A


	;**********************************
	; check for no bus activity/usb suspend

	1ms_suspend_timer:
		iord	usb_status					; read bus activity bit
		and		A, BUS_ACTIVITY				; mask off activity bit
		jnz		bus_activity
			
		inc		[suspend_count]				; increment suspend counter
		mov		A, [suspend_count]
		cmp		A, 04h						; if no bus activity for 3-4ms,
		jz		usb_suspend					; then go into low power suspend
		jmp		idle_timer_handler

 		usb_suspend:

		;******************************
		; disable unused pins		
		; buttons are already resistively pulled up
		; optics inputs are pulled down by external resistors
		; must turn off LED
		; NOTE - this firmware must change for each pin out 

			mov		A, OPTIC_CONTROL
			iowr	OPTIC_CONTROL_PORT


		; enable wakeup timer interrupt
			mov		A, (WAKEUP_INT | USB_RESET_INT)
			iowr 	global_int

		; suspend execution
  			mov		A, (SUSPEND | RUN)		; set suspend bit
 			ei
 			iowr	control
 			nop
			di

		; look for bus activity, if none go back into suspend
			iord	usb_status
			and		A, BUS_ACTIVITY
			jz		usb_suspend		

		; re-enable the optics in the case of the host wakeup
			mov		A, 00h
			iowr	OPTIC_CONTROL_PORT


		; re-enable interrupts
			mov		A, (1MS_INT | USB_RESET_INT | GPIO_INT)
			iowr 	global_int

		; reset wakeup timer
			mov		A, 00h
			mov		[wakeup_timer], A

	bus_activity:
		mov		A, 00h						; reset suspend counter
		mov		[suspend_count], A
		iord	usb_status
		and		A, ~(BUS_ACTIVITY | 10h)	; clear bus activity bit
		iowr	usb_status


	;**********************************
	; handle HID SET_IDLE request
	
	idle_timer_handler:
		mov		A, [idle]
		cmp		A, 00h
		jz		ms_timer_done

		inc		[idle_prescaler]
		mov		A, [idle_prescaler]
		cmp		A, 04h
		jz		decrement_idle_timer
		jmp		ms_timer_done

		decrement_idle_timer:
			mov		A, 00h
			mov		[idle_prescaler], A
			dec		[idle_timer]
			jz		reset_idle_timer
			jmp		ms_timer_done
			reset_idle_timer:
				mov		A, [idle]
				mov		[idle_timer], A
				mov		A, EVENT_PENDING
				mov		[event_machine], A


	ms_timer_done:
		pop A
		reti


;*******************************************************
;
;	Interrupt: Endpoint0
;	Purpose: Usb control endpoint handler.  This interrupt
;			handler formulates responses to SETUP and 
;			CONTROL READ, and NO-DATA CONTROL transactions. 

⌨️ 快捷键说明

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