Better layer support; disable L2 for now.
Need press/release tracking before sticky layers will work.
This commit is contained in:
parent
9a9ddaaa98
commit
d2a39a5cc4
5 changed files with 48 additions and 42 deletions
4
Makefile
4
Makefile
|
@ -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
|
||||||
|
|
10
README.md
10
README.md
|
@ -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.
|
||||||
|
|
42
layout.scm
42
layout.scm
|
@ -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))
|
||||||
|
|
17
menelaus.scm
17
menelaus.scm
|
@ -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)
|
||||||
|
|
13
test.rkt
13
test.rkt
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue