Fix a bug in releasing fn-layer shifted keys.
This commit is contained in:
parent
66f01f2fa2
commit
dcc363073b
6 changed files with 64 additions and 28 deletions
2
Makefile
2
Makefile
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
31
layout.scm
31
layout.scm
|
@ -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)
|
||||||
|
|
36
menelaus.scm
36
menelaus.scm
|
@ -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))))
|
||||||
|
|
||||||
|
|
16
test.rkt
16
test.rkt
|
@ -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) . (()))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue