{{ Flying Link Box (c) Diez Roggisch }} CON PRESS_PIN = 14 A_PIN = 13 B_PIN = 12 ' this is not time, but ' number of loops in the assembly code BOUNCETIME = 20 TX = 5 BPS = 115200 VAR long stack2[16] OBJ serial: "FullDuplexSerial" PUB start(peripheral_state_addr) cognew(@encoder_main, peripheral_state_addr) cognew(serial_communication(peripheral_state_addr), @stack2) PRI serial_communication(peripheral_state_addr) | state, h serial.Start(-1, TX, 0, BPS) repeat serial.tx("A") waitcnt(clkfreq / 5 + cnt) ' state := 0 ' repeat ' h := LONG[peripheral_state_addr] ' if h <> state ' state := h ' serial.hex(cnt, 8) ' serial.tx(32) ' serial.hex(state, 8) ' nl PRI nl serial.tx(13) serial.tx(10) DAT org 0 encoder_main :loop mov d0, encoder_position and d0, counter_mask or d0, pressed wrlong d0, par mov d0, ina test a_pin_mask, d0 wc if_c add a_filtered, #1 if_nc sub a_filtered, #1 max a_filtered, upper_limit min a_filtered, #1 test p_pin_mask, d0 wc if_c add p_filtered, #1 if_nc sub p_filtered, #1 max p_filtered, upper_limit min p_filtered, #1 cmp p_filtered, #1 wz if_z or pressed, pressed_flag if_nz andn pressed, pressed_flag tjnz counted, #:counted_case ' if we reached close to zero ' we count cmp a_filtered, lower_bound wc if_nc jmp #:loop ' we now counted a value and need ' to wait until the encoder has bounced ' up again mov counted, #1 ' check for direction test b_pin_mask, ina wc if_c subs encoder_position, #1 if_nc adds encoder_position, #1 jmp #:loop :counted_case cmp upper_bound, a_filtered wc ' we passed the high threshold, reset ' state counted so we look for the ' next falling flank again if_c mov counted, #0 jmp #:loop d0 long 0 encoder_position long 0 pressed long 0 a_pin_mask long 1 << A_PIN b_pin_mask long 1 << B_PIN p_pin_mask long 1 << PRESS_PIN a_filtered long BOUNCETIME b_filtered long BOUNCETIME p_filtered long BOUNCETIME counted long 0 upper_limit long BOUNCETIME lower_bound long BOUNCETIME * 20 / 100 upper_bound long BOUNCETIME * 80 / 100 pressed_flag long 1 << 16 counter_mask long $0000ffff