diff --git a/Makefile b/Makefile index 412f8b3..09608e0 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ test: ; racket test.rkt 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 avr-size $(TARGET).elf diff --git a/README.md b/README.md index e5adadc..c30b33c 100644 --- a/README.md +++ b/README.md @@ -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, 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 Copyright © 2014-2019 Phil Hagelberg and contributors diff --git a/layout.scm b/layout.scm index 1db4169..13f4514 100644 --- a/layout.scm +++ b/layout.scm @@ -1,5 +1,7 @@ ;;; 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 (define layers #f) (define current-layer #f) @@ -10,15 +12,22 @@ (define (set-layer 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 (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-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-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)) (define fn-layer - (vector (sft key-1) (sft key-2) key-up (sft key-dash) (sft key-equal) 0 - key-page-up key-7 key-8 key-9 (sft key-8) + (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 key-backspace - (sft key-3) key-left key-down key-right (sft key-4) 0 - key-page-down key-4 key-5 key-6 (sft key-right-bracket) + (sft key-9) key-left key-down key-right (sft key-0) (sft key-7) + 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-backtick key-1 key-2 key-3 key-backslash + key-dash key-equal (sft key-3) (sft key-dash) (sft key-equal) mod-ctrl + (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 key-space fn key-e key-0 key-right-bracket)) @@ -67,8 +76,8 @@ key-space fn key-quote key-left-bracket key-enter)) (define hard-dvorak-fn-layer - (vector (sft key-1) (sft key-2) key-up (sft key-left-bracket) (sft key-right-bracket) 0 - key-page-up key-7 key-8 key-9 (sft key-8) + (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-backspace) (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) diff --git a/menelaus.scm b/menelaus.scm index 1579a1f..60e0939 100644 --- a/menelaus.scm +++ b/menelaus.scm @@ -1,5 +1,4 @@ (include "keycodes.scm") -(include "layout.scm") (define rows (list 0 1 2 3)) (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 +;; 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 (define (member v lst) @@ -59,7 +65,7 @@ ;;;;;;;;;;;;;;;;;;; debouncing -(define debounce-passes 4) +(define debounce-passes 3) (define (debounce-matrix-aux last-scan passes-left) (if (< 0 passes-left) @@ -74,10 +80,10 @@ ;;;;;;;;;;;;;;;;;;; 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) - (if (= 0 (vector-ref last-keys-down n)) + (if (not (vector-ref last-keys-down n)) (vector-set! last-keys-down n key) (if (< n 9) (add-last-down-aux key (+ n 1)) @@ -87,8 +93,8 @@ (define (remove-last-down-aux key n) (if (< n 9) - (if (= key (vector-ref last-keys-down n)) - (vector-set! last-keys-down n 0) + (if (= key (or (vector-ref last-keys-down n) -1)) + (vector-set! last-keys-down n #f) (remove-last-down-aux key (+ n 1))) #f)) @@ -98,7 +104,7 @@ (define (remove-aux v lst checked all?) (if (null? lst) (reverse checked) - (if (= v (car lst)) + (if (equal? v (car lst)) (if all? (remove-aux v (cdr lst) checked all?) (reverse (append (cdr lst) checked))) @@ -117,7 +123,7 @@ (define (press/release-for keys-scanned) (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))) ;; save off press/release into last-keys-down for next cycle (for-each add-last-down (car p/r)) @@ -139,8 +145,6 @@ (define (press-modifier keycode key) (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)) (define (release-modifier keycode key n) @@ -169,17 +173,21 @@ (press-normal-key keycode 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))) (if (procedure? keycode) (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 (begin (vector-set! keycodes-down slot 0) (vector-set! keys-for-frame slot 0)) #f) - (if (modifier? keycode) - (release-modifier (unmodify keycode) key 0) + (if modifier-slot + (release-modifier modifier-slot key 0) #f))))) ;;;;;;;;;;;;;;;;;;; showtime @@ -203,7 +211,7 @@ (define (usb-send m k0 k1 k2 k3 k4 k5) ;; 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))))) (call-c-func "usb_send" mods k0 k1 k2 k3 k4 k5)))) diff --git a/test.rkt b/test.rkt index 57bf4b9..3bbee8d 100644 --- a/test.rkt +++ b/test.rkt @@ -59,8 +59,10 @@ ((3) . (() ,key-r)) ;; another single key ((2) . (() ,key-e)) + ;; the first key in the whole layout + ((0) . (() ,key-q)) ;; multiple normal keys - ((2 3) . (() ,key-r ,key-e)) + ((2 3) . (() ,key-e ,key-r)) ;; modifier keys (ctrl) ((27) . ((ctrl))) ;; two modifiers (shift+ctrl) get ORed together @@ -77,6 +79,18 @@ ((40 35 2) . ((super) ,key-up)) ;; releasing fn should leave the previously-pressed key on the fn layer!!! ((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) ((40) . (())) ((40 33) . (())) diff --git a/usb_keyboard.c b/usb_keyboard.c index 7625ebf..88613f0 100644 --- a/usb_keyboard.c +++ b/usb_keyboard.c @@ -26,6 +26,7 @@ #define USB_SERIAL_PRIVATE_INCLUDE #include "usb_keyboard.h" +#include /************************************************************************** * @@ -603,9 +604,10 @@ ISR(USB_COM_vect) UECONX = (1<