Better layer support; disable L2 for now.

Need press/release tracking before sticky layers will work.
This commit is contained in:
Phil Hagelberg 2019-07-03 20:31:25 -07:00
parent 9a9ddaaa98
commit d2a39a5cc4
5 changed files with 48 additions and 42 deletions

View file

@ -16,13 +16,13 @@ test: ; racket test.rkt
clean: ; -rm -f $(TARGET){,.hex} *.o *.elf *.s clean: ; -rm -f $(TARGET){,.hex} *.o *.elf *.s
count: ; cloc *.scm count: ; cloc menelaus.scm keycodes.scm
$(TARGET).hex: $(TARGET).elf $(TARGET).hex: $(TARGET).elf
avr-size $(TARGET).elf avr-size $(TARGET).elf
avr-objcopy --output-target=ihex $(TARGET).elf $(TARGET).hex avr-objcopy --output-target=ihex $(TARGET).elf $(TARGET).hex
%.s: %.scm $(TARGET).s: $(TARGET).scm layout.scm keycodes.scm
microscheme -m LEO $(TARGET).scm microscheme -m LEO $(TARGET).scm
%.elf: %.s usb_keyboard.s %.elf: %.s usb_keyboard.s

View file

@ -11,13 +11,15 @@ A firmware for the
* Multiple layers, momentary and sticky (limited only by memory) * Multiple layers, momentary and sticky (limited only by memory)
* Combo keys (a single keystroke can send a modifier and a non-modifier) * Combo keys (a single keystroke can send a modifier and a non-modifier)
* Bind arbitrary Scheme functions to a key * Bind arbitrary Scheme functions to a key
* ~255 lines of code * ~200 lines of code
## Usage ## Usage
This currently requires Microscheme with the addition of This currently requires Microscheme with the addition of
`vector-copy!` which at the time of this writing is only available on `vector-copy!` which at the time of this writing is only on the master branch.
[this branch](https://github.com/ryansuchocki/microscheme/pull/31).
Also requires [avrdude](https://www.nongnu.org/avrdude/) for uploading
to the device.
Replace `/dev/ttyACM0` with the path your OS assigns to the USB Replace `/dev/ttyACM0` with the path your OS assigns to the USB
bootloader of the microcontroller: bootloader of the microcontroller:
@ -38,6 +40,8 @@ into Racket and simulates the GPIO functions with a test harness:
## Known bugs ## Known bugs
Still working out some quirks with sticky layers.
If you hold the fn key, press a button (say Q) and then release fn If you hold the fn key, press a button (say Q) and then release fn
without releasing Q, it will send a keycode for Q rather than simply without releasing Q, it will send a keycode for Q rather than simply
leaving the previous fn+Q keycodes as held down. leaving the previous fn+Q keycodes as held down.

View file

@ -1,29 +1,22 @@
;;; this is the multidvorak layout ;;; this is the multidvorak layout
;; 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 (vector #f #f #f)) (define layers #f)
(define current-layer #f) (define current-layer #f)
(define momentary-layer #f) (define momentary-layer #f)
(define (fn) (define (fn)
(set! momentary-layer (vector-ref layers 1))) (set! momentary-layer (vector-ref layers 1)))
(define (set-layer-2) (define (set-layer n)
(set! current-layer (vector-ref layers 2))) (lambda () (set! current-layer (vector-ref layers n))))
(define (set-layer-0)
(set! current-layer (vector-ref layers 0)))
(define (set-layer-hard)
(set! current-layer (vector-ref layers 3)))
(define (reset) (define (reset)
#f) ;; TODO: uh, seriously. I need this. how. #f) ;; TODO: uh, seriously. I need this. how.
;;;; layers ;;;; layers
(vector-set! ; base (define base-layer
layers 0
(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-backslash
key-y key-u key-i key-o key-p key-y key-u key-i key-o key-p
@ -36,8 +29,7 @@
key-esc key-tab mod-super mod-shift key-backspace mod-alt key-esc key-tab mod-super mod-shift key-backspace mod-alt
key-space fn key-quote key-left-bracket key-enter)) key-space fn key-quote key-left-bracket key-enter))
(vector-set! ; fn (define fn-layer
layers 1
(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-dash) (sft key-equal) 0
key-page-up key-7 key-8 key-9 (sft key-8) key-page-up key-7 key-8 key-9 (sft key-8)
@ -47,25 +39,25 @@
key-dash key-equal (sft key-9) (sft key-0) (sft key-7) mod-ctrl 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-backtick key-1 key-2 key-3 key-backslash
set-layer-2 key-insert mod-super mod-shift key-backspace mod-alt ;; still got some bugs in layering to work out! make this reset for now
reset ;; (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))
(vector-set! ; l2 (function keys, etc) (define l2-layer
layers 2
(vector key-insert key-home key-up key-end key-page-up 0 (vector key-insert key-home key-up key-end key-page-up 0
key-up key-f7 key-f8 key-f9 key-f10 key-up key-f7 key-f8 key-f9 key-f10
key-delete key-left key-down key-right key-page-down 0 key-delete key-left key-down key-right key-page-down 0
key-down key-f4 key-f5 key-f6 key-f11 key-down key-f4 key-f5 key-f6 key-f11
0 key-vol-up 0 0 reset mod-ctrl (set-layer 0) key-vol-up 0 0 reset mod-ctrl
set-layer-hard key-f1 key-f2 key-f3 key-f12 (set-layer 4) key-f1 key-f2 key-f3 key-f12
0 key-vol-down mod-super mod-shift key-backspace mod-alt 0 key-vol-down mod-super mod-shift key-backspace mod-alt
key-space set-layer-0 key-printscreen key-scroll-lock key-pause)) key-space 0 key-printscreen key-scroll-lock key-pause))
(vector-set! ; hard dvorak (define hard-dvorak-layer
layers 3
(vector key-quote key-comma key-period key-p key-y key-backslash (vector key-quote key-comma key-period key-p key-y key-backslash
key-f key-g key-c key-r key-l key-f key-g key-c key-r key-l
@ -78,8 +70,7 @@
key-esc key-tab mod-super mod-shift key-backspace mod-alt key-esc key-tab mod-super mod-shift key-backspace mod-alt
key-space fn key-quote key-left-bracket key-enter)) key-space fn key-quote key-left-bracket key-enter))
(vector-set! ; hard dvorak fn (define hard-dvorak-fn-layer
layers 4
(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-left-bracket) (sft key-right-bracket) 0
key-page-up key-7 key-8 key-9 (sft key-8) key-page-up key-7 key-8 key-9 (sft key-8)
@ -89,5 +80,8 @@
key-left-bracket key-right-bracket (sft key-9) (sft key-0) (sft key-7) mod-ctrl key-left-bracket key-right-bracket (sft key-9) (sft key-0) (sft key-7) mod-ctrl
key-backtick key-1 key-2 key-3 key-backslash key-backtick key-1 key-2 key-3 key-backslash
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))
(set! layers (vector base-layer fn-layer l2-layer
hard-dvorak-layer hard-dvorak-fn-layer))

View file

@ -16,11 +16,11 @@
(define (scan-key keys-pressed key-count row col) (define (scan-key keys-pressed key-count row col)
;; pullup resistors mean a closed circuit is low rather than high ;; pullup resistors mean a closed circuit is low rather than high
(if (low? (vector-ref column-pins col)) (if (low? (vector-ref column-pins col))
(begin
(if (<= key-count max-keys) (if (<= key-count max-keys)
(begin
(vector-set! keys-pressed key-count (offset-for row col)) (vector-set! keys-pressed key-count (offset-for row col))
#f)
(+ key-count 1)) (+ key-count 1))
key-count)
key-count)) key-count))
(define (scan-column keys-pressed key-count row columns-left) (define (scan-column keys-pressed key-count row columns-left)
@ -47,7 +47,7 @@
(define this-scan (vector 0 0 0 0 0 0 0)) (define this-scan (vector 0 0 0 0 0 0 0))
(define last-scan (vector 0 0 0 0 0 0 0)) (define last-scan (vector 0 0 0 0 0 0 0))
(define debounce-passes 8) (define debounce-passes 4)
(define (debounce-matrix keys-pressed last-count passes-left) (define (debounce-matrix keys-pressed last-count passes-left)
;; older versions of microscheme don't have vector-copy!, only vector-copy ;; older versions of microscheme don't have vector-copy!, only vector-copy
@ -80,9 +80,7 @@
(define (call-functions keys-pressed key-count) (define (call-functions keys-pressed key-count)
(if (< 0 key-count) (if (< 0 key-count)
(let ((code (lookup keys-pressed key-count))) (let ((code (lookup keys-pressed key-count)))
(if (procedure? code) (and (procedure? code) (code))
(code)
#f)
(call-functions keys-pressed (- key-count 1))) (call-functions keys-pressed (- key-count 1)))
#f)) #f))
@ -93,15 +91,14 @@
(if (= 0 key-count) (if (= 0 key-count)
(vector->list keycodes) (vector->list keycodes)
(let ((keycode (keycode-for keys-pressed key-count keycodes))) (let ((keycode (keycode-for keys-pressed key-count keycodes)))
(if keycode (and keycode
(vector-set! keycodes key-count keycode) (vector-set! keycodes key-count keycode))
#f)
(keycodes-for keys-pressed (- key-count 1) keycodes)))) (keycodes-for keys-pressed (- key-count 1) keycodes))))
;;;;;;;;;;;;;;;;;;; showtime ;;;;;;;;;;;;;;;;;;; showtime
(define (init) (define (init)
(set-layer-0) (set! current-layer (vector-ref layers 0))
(for-each-vector output row-pins) (for-each-vector output row-pins)
(for-each-vector high row-pins) (for-each-vector high row-pins)
(for-each-vector input column-pins) (for-each-vector input column-pins)

View file

@ -68,6 +68,16 @@
((40 35 2) . (8 ,key-up 0 0 0 0 0)) ((40 35 2) . (8 ,key-up 0 0 0 0 0))
;; 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) . (0 ,key-up 0 0 0 0 0)) ;; ((2) . (0 ,key-up 0 0 0 0 0))
;; changing to L2 (fn+esc)
((40 33) . (0 0 0 0 0 0 0))
;; fn+esc should stay on L2 across multiple scans
((40 33) . (0 0 0 0 0 0 0))
;; hitting an L2 key
;; ((1) . (0 ,key-home 0 0 0 0 0))
;; back to base (key above esc)
;; ((22) . (0 0 0 0 0 0 0))
;; base layer key
((2) . (0 ,key-e 0 0 0 0 0))
)) ))
(define test-data (make-test-data)) (define test-data (make-test-data))
@ -80,7 +90,8 @@
(cons (format "Expected ~s, got ~s~n" expected actual) failures))) (cons (format "Expected ~s, got ~s~n" expected actual) failures)))
(define (finish) (define (finish)
(printf (string-join failures "~n" #:before-first "~n" #:after-last "~n")) (printf (string-join (reverse failures)
"~n" #:before-first "~n" #:after-last "~n"))
(exit (if (empty? failures) 0 1))) (exit (if (empty? failures) 0 1)))
;; we can perform our checks here and make changes to the pin state. ;; we can perform our checks here and make changes to the pin state.