📄 mouse.asm
字号:
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 + -