Fix a bug in releasing fn-layer shifted keys.

This commit is contained in:
Phil Hagelberg 2020-02-20 19:12:46 -08:00
parent 66f01f2fa2
commit dcc363073b
6 changed files with 64 additions and 28 deletions

View file

@ -16,7 +16,7 @@ test: ; racket test.rkt
clean: ; -rm -f $(TARGET){,.hex} *.o *.elf *.s clean: ; -rm -f $(TARGET){,.hex} *.o *.elf *.s
count: ; cloc menelaus.scm keycodes.scm count: ; cloc menelaus.scm keycodes.scm layout.scm
$(TARGET).hex: $(TARGET).elf $(TARGET).hex: $(TARGET).elf
avr-size $(TARGET).elf avr-size $(TARGET).elf

View file

@ -49,6 +49,9 @@ into Racket and simulates the GPIO functions with a test harness:
If you hold down two keys which contain a modifier (for instance, If you hold down two keys which contain a modifier (for instance,
shift and !) and release one of them, it will count as if both are released. shift and !) and release one of them, it will count as if both are released.
The reset function has no effect; hard-reset must be used to reflash
the firmware.
## License ## License
Copyright © 2014-2019 Phil Hagelberg and contributors Copyright © 2014-2019 Phil Hagelberg and contributors

View file

@ -1,5 +1,7 @@
;;; this is the multidvorak layout ;;; this is the multidvorak layout
;; it will work for the 44-key Atreus 2 or the 42-key Atreus 1.
;; we have to declare this up front and set it later because of circularity ;; we have to declare this up front and set it later because of circularity
(define layers #f) (define layers #f)
(define current-layer #f) (define current-layer #f)
@ -10,15 +12,22 @@
(define (set-layer n) (define (set-layer n)
(lambda (_) (set! current-layer (vector-ref layers n)))) (lambda (_) (set! current-layer (vector-ref layers n))))
(define (reset _) (call-c-func "reset")) (define (reset _) (call-c-func "reset")) ; broken
;; on the Atreus 1, we need to expose backtick on the fn layer, but on
;; the Atreus 2 it has its own key, so we put percent there instead
(define backtick-or-percent
key-backtick
;; (sft key-5)
)
;;;; layers ;;;; layers
(define base-layer (define base-layer
(vector key-q key-w key-e key-r key-t key-backslash (vector key-q key-w key-e key-r key-t key-backtick
key-y key-u key-i key-o key-p key-y key-u key-i key-o key-p
key-a key-s key-d key-f key-g key-backtick key-a key-s key-d key-f key-g key-backslash
key-h key-j key-k key-l key-semicolon key-h key-j key-k key-l key-semicolon
key-z key-x key-c key-v key-b mod-ctrl key-z key-x key-c key-v key-b mod-ctrl
@ -28,14 +37,14 @@
key-space fn key-quote key-left-bracket key-enter)) key-space fn key-quote key-left-bracket key-enter))
(define fn-layer (define fn-layer
(vector (sft key-1) (sft key-2) key-up (sft key-dash) (sft key-equal) 0 (vector (sft key-1) (sft key-2) key-up (sft key-4) backtick-or-percent (sft key-6)
key-page-up key-7 key-8 key-9 (sft key-8) key-page-up key-7 key-8 key-9 key-backspace
(sft key-3) key-left key-down key-right (sft key-4) 0 (sft key-9) key-left key-down key-right (sft key-0) (sft key-7)
key-page-down key-4 key-5 key-6 (sft key-right-bracket) key-page-down key-4 key-5 key-6 key-backslash
key-dash key-equal (sft key-9) (sft key-0) (sft key-7) mod-ctrl key-dash key-equal (sft key-3) (sft key-dash) (sft key-equal) mod-ctrl
key-backtick key-1 key-2 key-3 key-backslash (sft key-8) key-1 key-2 key-3 (sft key-right-bracket)
(set-layer 2) key-insert mod-super mod-shift key-backspace mod-alt (set-layer 2) key-insert mod-super mod-shift key-backspace mod-alt
key-space fn key-e key-0 key-right-bracket)) key-space fn key-e key-0 key-right-bracket))
@ -67,8 +76,8 @@
key-space fn key-quote key-left-bracket key-enter)) key-space fn key-quote key-left-bracket key-enter))
(define hard-dvorak-fn-layer (define hard-dvorak-fn-layer
(vector (sft key-1) (sft key-2) key-up (sft key-left-bracket) (sft key-right-bracket) 0 (vector (sft key-1) (sft key-2) key-up (sft key-4) (sft key-5) (sft key-6)
key-page-up key-7 key-8 key-9 (sft key-8) key-page-up key-7 key-8 key-9 (sft key-backspace)
(sft key-3) key-left key-down key-right (sft key-4) 0 (sft key-3) key-left key-down key-right (sft key-4) 0
key-page-down key-4 key-5 key-6 (sft key-equal) key-page-down key-4 key-5 key-6 (sft key-equal)

View file

@ -1,5 +1,4 @@
(include "keycodes.scm") (include "keycodes.scm")
(include "layout.scm")
(define rows (list 0 1 2 3)) (define rows (list 0 1 2 3))
(define row-pins (vector 3 2 1 0)) (define row-pins (vector 3 2 1 0))
@ -8,6 +7,13 @@
(define max-keys 10) ; single USB frame can only send 6 keycodes plus modifiers (define max-keys 10) ; single USB frame can only send 6 keycodes plus modifiers
;; pcbdown flip, comment out for normal
;; (begin (set! mod-alt (modify 1))
;; (set! mod-ctrl (modify 3))
;; (set! column-pins (vector 11 12 18 19 10 4 7 8 9 5 6)))
(include "layout.scm")
;;;;;;;;;;;;;;;;;;; utils ;;;;;;;;;;;;;;;;;;; utils
(define (member v lst) (define (member v lst)
@ -59,7 +65,7 @@
;;;;;;;;;;;;;;;;;;; debouncing ;;;;;;;;;;;;;;;;;;; debouncing
(define debounce-passes 4) (define debounce-passes 3)
(define (debounce-matrix-aux last-scan passes-left) (define (debounce-matrix-aux last-scan passes-left)
(if (< 0 passes-left) (if (< 0 passes-left)
@ -74,10 +80,10 @@
;;;;;;;;;;;;;;;;;;; press and release tracking ;;;;;;;;;;;;;;;;;;; press and release tracking
(define last-keys-down (vector 0 0 0 0 0 0 0 0 0 0)) (define last-keys-down (vector #f #f #f #f #f #f #f #f #f #f))
(define (add-last-down-aux key n) (define (add-last-down-aux key n)
(if (= 0 (vector-ref last-keys-down n)) (if (not (vector-ref last-keys-down n))
(vector-set! last-keys-down n key) (vector-set! last-keys-down n key)
(if (< n 9) (if (< n 9)
(add-last-down-aux key (+ n 1)) (add-last-down-aux key (+ n 1))
@ -87,8 +93,8 @@
(define (remove-last-down-aux key n) (define (remove-last-down-aux key n)
(if (< n 9) (if (< n 9)
(if (= key (vector-ref last-keys-down n)) (if (= key (or (vector-ref last-keys-down n) -1))
(vector-set! last-keys-down n 0) (vector-set! last-keys-down n #f)
(remove-last-down-aux key (+ n 1))) (remove-last-down-aux key (+ n 1)))
#f)) #f))
@ -98,7 +104,7 @@
(define (remove-aux v lst checked all?) (define (remove-aux v lst checked all?)
(if (null? lst) (if (null? lst)
(reverse checked) (reverse checked)
(if (= v (car lst)) (if (equal? v (car lst))
(if all? (if all?
(remove-aux v (cdr lst) checked all?) (remove-aux v (cdr lst) checked all?)
(reverse (append (cdr lst) checked))) (reverse (append (cdr lst) checked)))
@ -117,7 +123,7 @@
(define (press/release-for keys-scanned) (define (press/release-for keys-scanned)
(let ((p/r (press/release-aux (list) (let ((p/r (press/release-aux (list)
(remove-all 0 (vector->list last-keys-down)) (remove-all #f (vector->list last-keys-down))
keys-scanned))) keys-scanned)))
;; save off press/release into last-keys-down for next cycle ;; save off press/release into last-keys-down for next cycle
(for-each add-last-down (car p/r)) (for-each add-last-down (car p/r))
@ -139,8 +145,6 @@
(define (press-modifier keycode key) (define (press-modifier keycode key)
(vector-set! modifiers (- keycode 1) 1) (vector-set! modifiers (- keycode 1) 1)
;; TODO: there is one bug here: if multiple keys have caused a modifier to be
;; active, then releasing only one of the keys will release the modifier.
(vector-set! keys-for-modifiers (- keycode 1) key)) (vector-set! keys-for-modifiers (- keycode 1) key))
(define (release-modifier keycode key n) (define (release-modifier keycode key n)
@ -169,17 +173,21 @@
(press-normal-key keycode key))))) (press-normal-key keycode key)))))
(define (release-key key) (define (release-key key)
;; lookup here looks it up in the current layer, even if it was pressed in
;; the momentary layer. these need to be consistent across layers or tracked
;; in a similar manner as keys-for-frame.
(let ((keycode (lookup key))) (let ((keycode (lookup key)))
(if (procedure? keycode) (if (procedure? keycode)
(keycode #f) (keycode #f)
(let ((slot (find keys-for-frame key))) (let ((slot (find keys-for-frame key))
(modifier-slot (find keys-for-modifiers key)))
(if slot (if slot
(begin (begin
(vector-set! keycodes-down slot 0) (vector-set! keycodes-down slot 0)
(vector-set! keys-for-frame slot 0)) (vector-set! keys-for-frame slot 0))
#f) #f)
(if (modifier? keycode) (if modifier-slot
(release-modifier (unmodify keycode) key 0) (release-modifier modifier-slot key 0)
#f))))) #f)))))
;;;;;;;;;;;;;;;;;;; showtime ;;;;;;;;;;;;;;;;;;; showtime
@ -203,7 +211,7 @@
(define (usb-send m k0 k1 k2 k3 k4 k5) (define (usb-send m k0 k1 k2 k3 k4 k5)
;; call-c-func is a special form and cannot be applied ;; call-c-func is a special form and cannot be applied
(let ((mods (+ (vector-ref m 0) (* (vector-ref m 1) 2)))) ; plus isn't variadic (let ((mods (+ (vector-ref m 0) (* (vector-ref m 1) 2)))) ; + isn't variadic
(let ((mods (+ mods (+ (* (vector-ref m 2) 4) (* (vector-ref m 3) 8))))) (let ((mods (+ mods (+ (* (vector-ref m 2) 4) (* (vector-ref m 3) 8)))))
(call-c-func "usb_send" mods k0 k1 k2 k3 k4 k5)))) (call-c-func "usb_send" mods k0 k1 k2 k3 k4 k5))))

View file

@ -59,8 +59,10 @@
((3) . (() ,key-r)) ((3) . (() ,key-r))
;; another single key ;; another single key
((2) . (() ,key-e)) ((2) . (() ,key-e))
;; the first key in the whole layout
((0) . (() ,key-q))
;; multiple normal keys ;; multiple normal keys
((2 3) . (() ,key-r ,key-e)) ((2 3) . (() ,key-e ,key-r))
;; modifier keys (ctrl) ;; modifier keys (ctrl)
((27) . ((ctrl))) ((27) . ((ctrl)))
;; two modifiers (shift+ctrl) get ORed together ;; two modifiers (shift+ctrl) get ORed together
@ -77,6 +79,18 @@
((40 35 2) . ((super) ,key-up)) ((40 35 2) . ((super) ,key-up))
;; releasing fn should leave the previously-pressed key on the fn layer!!! ;; releasing fn should leave the previously-pressed key on the fn layer!!!
((2) . (() ,key-up)) ((2) . (() ,key-up))
;; fn key alone
((40) . (()))
;; fn key and *
((40 28) . ((shift) ,key-8))
;; fn is released
((28) . ((shift) ,key-8))
;; * is released
(() . (()))
;; normal key doesn't leave shift down
((0) . (() ,key-q))
;; changing to L2 (fn+esc) ;; changing to L2 (fn+esc)
((40) . (())) ((40) . (()))
((40 33) . (())) ((40 33) . (()))

View file

@ -26,6 +26,7 @@
#define USB_SERIAL_PRIVATE_INCLUDE #define USB_SERIAL_PRIVATE_INCLUDE
#include "usb_keyboard.h" #include "usb_keyboard.h"
#include <util/delay.h>
/************************************************************************** /**************************************************************************
* *
@ -603,9 +604,10 @@ ISR(USB_COM_vect)
UECONX = (1<<STALLRQ) | (1<<EPEN); // stall UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
} }
// this fails to enter the bootloader
void reset(void) { void reset(void) {
UDCON = 1; USBCON = (1<<FRZCLK); UCSR1B = 0; UDCON = 1; USBCON = (1<<FRZCLK); UCSR1B = 0;
// _delay_ms(5); _delay_ms(5);
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0; TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;