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

📄 mouse.asm

📁 Cypress USB HID code
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		mov		A, X0						; enable gpio interrupt
		iowr	port0_int
		mov		A, 80h | X1 | Y0 | Y1		; 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_x0: 						; wait for gpio interrupt to occur			
			cmp		A, [gpio_int_flag]
			jz		wait_timer_x0

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

		;***** restore X0 port to strong - drive 1 strength
		mov		A, 00h
		iowr	port0_int
		mov		A, LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON | X0 | X1 | Y0 | Y1
		iowr	X_OPTICS_PORT				; drive 'b1 onto pin
		mov		A, 80h | X0 | X1 | Y0 | Y1
		iowr	port0_mode0		

		mov		A, X		; check if interrupt went off during measurement
		cmp		A, 00h
		jz		x0_no_interrupt_went_off
		x0_interrupt_went_off:
			mov		A, [x_last_state]
			mov		[x_current_state], A
			jmp		measure_y0_optics

		x0_no_interrupt_went_off:
			mov		A, [optic_finish_time]
			sub		A, [optic_start_time]	; get time difference
			push	A

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

			; set new max time
			mov		[x0_max_time], A	
			; recalculate average
			add		A, [x0_min_time]
			jc		calc_x0_xavg_with_carry
				calc_x0_xavg_without_carry:
					asr		A				; divide value by 2
					mov		[x0_avg_time], A				
					jmp		calc_x0_xavg_hysteresis

				calc_x0_xavg_with_carry:
					asr		A
					or		A, 80h			; add msb back in to average
					mov		[x0_avg_time], A
					
				calc_x0_xavg_hysteresis:
					mov		A, [x0_max_time]	; hysteresis high value
					sub		A, [x0_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [x0_avg_time]
					mov		[x0_hyst_high], A

					mov		A, [x0_avg_time]	; hysteresis low value
					sub		A, [x0_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [x0_avg_time]
					sub		A, [temp]
					mov		[x0_hyst_low], A
					

		; if time differnce is less than max time, store this as 
		; the new max time and recalculate the average time
		compare_x0_min:
			pop		A
			push	A
			cmp		A, [x0_min_time]
			jnc		compare_x0_avg
			; set new min time
			mov		[x0_min_time], A
			; recalculate average
			add		A, [x0_max_time]
			jc		calc_x0_mavg_with_carry
				calc_x0_mavg_without_carry:
					asr		A				; divide value by 2
					mov		[x0_avg_time], A
					jmp		calc_x0_mavg_hysteresis

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

				calc_x0_mavg_hysteresis:
					mov		A, [x0_max_time]	; hysteresis high value
					sub		A, [x0_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [x0_avg_time]
					mov		[x0_hyst_high], A

					mov		A, [x0_avg_time]	; hysteresis low value
					sub		A, [x0_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [x0_avg_time]
					sub		A, [temp]
					mov		[x0_hyst_low], A


		; compare the timer value to the average value to determine if
		; the output value was a 1 or 0
		compare_x0_avg:
			pop		A						; get last measured time
			cmp		A, [x0_hyst_low]
			jc		x0_is_zero
			cmp		A, [x0_hyst_high]
			jnc		x0_is_one

			x0_invalid:
				mov		A, [x_last_state]
				and		A, 01h
				or		[x_current_state], A
				jmp		measure_x1_optics

			x0_is_one:
				mov		A, 01h
				or		[x_current_state], A

			x0_is_zero:

				

		;*****************
		;
		;	optic X1
		;
		;*****************

		measure_x1_optics:

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


		;***** release optic into hi-z mode
		mov		A, 00h						; clear gpio interrupt flag
		mov		[gpio_int_flag], A
		mov		A, X1						; enable X1 interrupt
		iowr	port0_int
		mov		A, 80h | X0 | Y0 | Y1		; release optic into 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_x1:						; wait for rising edge gpio
			cmp		A, [gpio_int_flag]
			jz		wait_timer_x1

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


		;***** restore X1 port to medium - drive 1 strength
		mov		A, 00h						; disable gpio interrupts
		iowr	port0_int
		mov		A, LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON | X0 | X1 | Y0 | Y1
		iowr	X_OPTICS_PORT				; drive 'b1 onto pin
		mov		A, 80h | X0 | X1 | Y0 | Y1
		iowr	port0_mode0		


		;***** check if interrupt went off during measurement
		mov		A, X						; check if interrupt went off
		cmp		A, 00h						; data should be thrown away if this
		jz		x1_no_interrupt_went_off	; occurred
		x1_interrupt_went_off:
			mov		A, [x_last_state]
			mov		[x_current_state], A
			jmp		measure_y0_optics

		x1_no_interrupt_went_off:
			mov		A, [optic_finish_time]  ; get the finish time measurement
			sub		A, [optic_start_time]	; get time difference
			push	A						; stash time difference on data stack

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

			; set new max time
			mov		[x1_max_time], A	
			; recalculate average
			add		A, [x1_min_time]
			jc		calc_x1_xavg_with_carry
				calc_x1_xavg_without_carry:
					asr		A		; divide value by 2
					mov		[x1_avg_time], A				
					jmp		calc_x1_xavg_hysteresis

				calc_x1_xavg_with_carry:
					asr		A
					or		A, 80h	; add msb back in to average
					mov		[x1_avg_time], A
					
				calc_x1_xavg_hysteresis:
					mov		A, [x1_max_time]	; hysteresis high value
					sub		A, [x1_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [x1_avg_time]
					mov		[x1_hyst_high], A

					mov		A, [x1_avg_time]	; hysteresis low value
					sub		A, [x1_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [x1_avg_time]
					sub		A, [temp]
					mov		[x1_hyst_low], A
					

		; if time differnce is less than max time, store this as 
		; the new max time and recalculate the average time
		compare_x1_min:
			pop		A
			push	A
			cmp		A, [x1_min_time]
			jnc		compare_x1_avg
			; set new min time
			mov		[x1_min_time], A
			; recalculate average
			add		A, [x1_max_time]
			jc		calc_x1_mavg_with_carry
				calc_x1_mavg_without_carry:
					asr		A		; divide value by 2
					mov		[x1_avg_time], A
					jmp		calc_x1_mavg_hysteresis

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

				calc_x1_mavg_hysteresis:
					mov		A, [x1_max_time]	; hysteresis high value
					sub		A, [x1_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [x1_avg_time]
					mov		[x1_hyst_high], A

					mov		A, [x1_avg_time]	; hysteresis low value
					sub		A, [x1_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [x1_avg_time]
					sub		A, [temp]
					mov		[x1_hyst_low], A


		; compare the timer value to the average value to determine if
		; the output value was a 1 or 0
		compare_x1_avg:
			pop		A			; get last measured time
			cmp		A, [x1_hyst_low]
			jc		x1_is_zero
			cmp		A, [x1_hyst_high]
			jnc		x1_is_one

			x1_invalid:
				mov		A, [x_last_state]
				and		A, 02h
				or		[x_current_state], A
				jmp		measure_y0_optics

			x1_is_one:
				mov		A, 02h
				or		[x_current_state], A

			x1_is_zero:



	;*********************
	;
	;	optic Y0
	;
	;*********************


		measure_y0_optics:

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


		;***** release optic into hi-z mode
		mov		A, 00h						; clear gpio interrupt flag
		mov		[gpio_int_flag], A
		mov		A, Y0						; enable gpio interrupt
		iowr	port0_int
		mov		A, 80h | X0 | X1 | Y1		; 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_y0:						; wait for gpio interrupt to occur
			cmp		A, [gpio_int_flag]
			jz		wait_timer_y0
		
		mov		X, [int_flag]				; store the int_flag in X

		;***** restore Y0 port to medium - drive 1 strength
		mov		A, 00h
		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
		mov		A, X						; retrieve the int_flag variable		
		cmp		A, 00h
		jz		y0_no_interrupt_went_off
		y0_interrupt_went_off:
			mov		A, [y_last_state]
			mov		[y_current_state], A
			jmp		analyze_x_optics

		y0_no_interrupt_went_off:
			mov		A, [optic_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_y0_max:
			cmp		A, [y0_max_time]
			jc		compare_y0_min
			cmp		A, THRESHOLD_TIME		; guard band in case we hit an
			jnc		compare_y0_min			; interrupt during timer measurement

			; set new max time
			mov		[y0_max_time], A	
			; recalculate average
			add		A, [y0_min_time]
			jc		calc_y0_xavg_with_carry
				calc_y0_xavg_without_carry:
					asr		A		; divide value by 2
					mov		[y0_avg_time], A				
					jmp		calc_y0_xavg_hysteresis

				calc_y0_xavg_with_carry:
					asr		A
					or		A, 80h	; add msb back in to average
					mov		[y0_avg_time], A
					
				calc_y0_xavg_hysteresis:
					mov		A, [y0_max_time]	; hysteresis high value
					sub		A, [y0_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [y0_avg_time]
					mov		[y0_hyst_high], A

					mov		A, [y0_avg_time]	; hysteresis low value
					sub		A, [y0_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [y0_avg_time]
					sub		A, [temp]
					mov		[y0_hyst_low], A
					

		; if time differnce is less than max time, store this as 
		; the new max time and recalculate the average time
		compare_y0_min:
			pop		A
			push	A
			cmp		A, [y0_min_time]
			jnc		compare_y0_avg
			; set new min time
			mov		[y0_min_time], A
			; recalculate average
			add		A, [y0_max_time]
			jc		calc_y0_mavg_with_carry
				calc_y0_mavg_without_carry:
					asr		A		; divide value by 2
					mov		[y0_avg_time], A
					jmp		calc_y0_mavg_hysteresis

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

				calc_y0_mavg_hysteresis:
					mov		A, [y0_max_time]	; hysteresis high value
					sub		A, [y0_avg_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					add		A, [y0_avg_time]
					mov		[y0_hyst_high], A

					mov		A, [y0_avg_time]	; hysteresis low value
					sub		A, [y0_min_time]
					asr		A	; 50%
					asr		A	; 25%
					;asr	A	; 12.5%
					and		A, HYST_MASK
					mov		[temp], A
					mov		A, [y0_avg_time]
					sub		A, [temp]
					mov		[y0_hyst_low], A


		; compare the timer value to the average value to determine if
		; the output value was a 1 or 0
		compare_y0_avg:
			pop		A						; get last measured time
			cmp		A, [y0_hyst_low]
			jc		y0_is_zero
			cmp		A, [y0_hyst_high]
			jnc		y0_is_one

			y0_invalid:
				mov		A, [y_last_state]
				and		A, 01h
				or		[y_current_state], A
				jmp		measure_y1_optics

			y0_is_one:
				mov		A, 01h
				or		[y_current_state], A

			y0_is_zero:


⌨️ 快捷键说明

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