Refactor to use lists for scans of the matrix instead of vectors.
This commit is contained in:
parent
1b49ec4319
commit
8110923ba0
2 changed files with 54 additions and 61 deletions
109
menelaus.scm
109
menelaus.scm
|
@ -6,70 +6,61 @@
|
||||||
(define columns (list 0 1 2 3 4 5 6 7 8 9 10))
|
(define columns (list 0 1 2 3 4 5 6 7 8 9 10))
|
||||||
(define column-pins (vector 6 5 9 8 7 4 10 19 18 12 11))
|
(define column-pins (vector 6 5 9 8 7 4 10 19 18 12 11))
|
||||||
|
|
||||||
(define max-keys 6) ; a single USB frame can only send 6 keycodes plus modifiers
|
(define max-keys 10) ; single USB frame can only send 6 keycodes plus modifiers
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;; matrix
|
;;;;;;;;;;;;;;;;;;; matrix
|
||||||
|
|
||||||
(define (offset-for row col)
|
(define (offset-for row col)
|
||||||
(+ col (* row (length columns))))
|
(+ col (* row (length columns))))
|
||||||
|
|
||||||
(define (scan-key keys-pressed key-count row col)
|
(define (scan-key scan row col)
|
||||||
|
(if (and (< (length scan) max-keys)
|
||||||
;; 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))
|
(low? (vector-ref column-pins col)))
|
||||||
(if (<= key-count max-keys)
|
(cons (offset-for row col) scan)
|
||||||
(begin
|
scan))
|
||||||
(vector-set! keys-pressed key-count (offset-for row col))
|
|
||||||
(+ key-count 1))
|
|
||||||
key-count)
|
|
||||||
key-count))
|
|
||||||
|
|
||||||
(define (scan-column keys-pressed key-count row columns-left)
|
(define (scan-column scan row columns-left)
|
||||||
(if (= (length columns-left) 0)
|
(if (empty? columns-left)
|
||||||
key-count
|
scan
|
||||||
(let ((key-count (scan-key keys-pressed key-count
|
(scan-column (scan-key scan row (car columns-left))
|
||||||
row (car columns-left))))
|
row (cdr columns-left))))
|
||||||
(scan-column keys-pressed key-count row (cdr columns-left)))))
|
|
||||||
|
|
||||||
(define (activate-row row)
|
(define (activate-row row)
|
||||||
(for-each-vector high row-pins)
|
(for-each-vector high row-pins)
|
||||||
(low (vector-ref row-pins row)))
|
(low (vector-ref row-pins row)))
|
||||||
|
|
||||||
(define (scan-matrix keys-pressed key-count rows-left)
|
(define (scan-matrix scan rows-left)
|
||||||
(if (= (length rows-left) 0)
|
(if (empty? rows-left)
|
||||||
key-count
|
scan
|
||||||
(let ((_ (activate-row (car rows-left)))
|
(begin
|
||||||
(key-count (scan-column keys-pressed key-count
|
(activate-row (car rows-left))
|
||||||
(car rows-left) columns)))
|
(scan-matrix (scan-column scan (car rows-left) columns)
|
||||||
(scan-matrix keys-pressed key-count (cdr rows-left)))))
|
(cdr rows-left)))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;; debouncing
|
;;;;;;;;;;;;;;;;;;; debouncing
|
||||||
|
|
||||||
(define this-scan (vector 0 0 0 0 0 0 0))
|
|
||||||
(define last-scan (vector 0 0 0 0 0 0 0))
|
|
||||||
|
|
||||||
(define debounce-passes 4)
|
(define debounce-passes 4)
|
||||||
|
|
||||||
(define (debounce-matrix keys-pressed last-count passes-left)
|
(define (debounce-matrix-aux last-scan passes-left)
|
||||||
;; older versions of microscheme don't have vector-copy!, only vector-copy
|
|
||||||
;; which does the same thing but takes the arguments in a different order
|
|
||||||
(vector-copy! last-scan 0 this-scan 0 6)
|
|
||||||
(if (< 0 passes-left)
|
(if (< 0 passes-left)
|
||||||
(let ((this-count (scan-matrix this-scan 1 rows)))
|
(let ((this-scan (scan-matrix (list) rows)))
|
||||||
(if (and (= this-count last-count)
|
(if (equal? this-scan last-scan)
|
||||||
(equal? this-scan last-scan))
|
(debounce-matrix-aux this-scan (- passes-left 1))
|
||||||
(debounce-matrix keys-pressed this-count (- passes-left 1))
|
(debounce-matrix-aux this-scan debounce-passes)))
|
||||||
(debounce-matrix keys-pressed this-count passes-left)))
|
last-scan))
|
||||||
(begin (vector-copy! keys-pressed 0 this-scan 0 6)
|
|
||||||
last-count)))
|
(define (debounce-matrix)
|
||||||
|
(debounce-matrix-aux (list) debounce-passes))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;; layout
|
;;;;;;;;;;;;;;;;;;; layout
|
||||||
|
|
||||||
(define (lookup keys-pressed which-key)
|
(define (lookup key-pos)
|
||||||
(let ((layout (or momentary-layer current-layer)))
|
(let ((layout (or momentary-layer current-layer)))
|
||||||
(vector-ref layout (vector-ref keys-pressed which-key))))
|
(vector-ref layout key-pos)))
|
||||||
|
|
||||||
(define (keycode-for keys-pressed which-key keycodes)
|
(define (keycode-for key-pos keycodes)
|
||||||
(let ((code (lookup keys-pressed which-key)))
|
(let ((code (lookup key-pos)))
|
||||||
;; (printf "keycode ~s ~s~n" code which-key)
|
;; (printf "keycode ~s ~s~n" code which-key)
|
||||||
(if (modifier? code)
|
(if (modifier? code)
|
||||||
(begin (vector-set! keycodes 0 (+ (vector-ref keycodes 0)
|
(begin (vector-set! keycodes 0 (+ (vector-ref keycodes 0)
|
||||||
|
@ -77,23 +68,28 @@
|
||||||
(uncombo code))
|
(uncombo code))
|
||||||
(and (not (procedure? code)) code))))
|
(and (not (procedure? code)) code))))
|
||||||
|
|
||||||
(define (call-functions keys-pressed key-count)
|
(define (call-functions keys-scanned)
|
||||||
(if (< 0 key-count)
|
(if (empty? keys-scanned)
|
||||||
(let ((code (lookup keys-pressed key-count)))
|
#f
|
||||||
|
(let ((code (lookup (car keys-scanned))))
|
||||||
(and (procedure? code) (code))
|
(and (procedure? code) (code))
|
||||||
(call-functions keys-pressed (- key-count 1)))
|
(call-functions (cdr keys-scanned)))))
|
||||||
#f))
|
|
||||||
|
(define (first-zero v n)
|
||||||
|
(if (or (= 0 (vector-ref v n)) (= 6 n))
|
||||||
|
n
|
||||||
|
(first-zero v (+ n 1))))
|
||||||
|
|
||||||
;; translate key numbers into specific USB keycodes
|
;; translate key numbers into specific USB keycodes
|
||||||
(define (keycodes-for keys-pressed key-count keycodes)
|
(define (keycodes-for keys-scanned keycodes)
|
||||||
;; this happens before we look up "regular" keycodes because it changes layers
|
;; this happens before we look up "regular" keycodes because it changes layers
|
||||||
(call-functions keys-pressed key-count)
|
(call-functions keys-scanned)
|
||||||
(if (= 0 key-count)
|
(if (empty? keys-scanned)
|
||||||
(vector->list keycodes)
|
(vector->list keycodes)
|
||||||
(let ((keycode (keycode-for keys-pressed key-count keycodes)))
|
(let ((keycode (keycode-for (car keys-scanned) keycodes)))
|
||||||
(and keycode
|
(and keycode
|
||||||
(vector-set! keycodes key-count keycode))
|
(vector-set! keycodes (first-zero keycodes 1) keycode))
|
||||||
(keycodes-for keys-pressed (- key-count 1) keycodes))))
|
(keycodes-for (cdr keys-scanned) keycodes))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;; showtime
|
;;;;;;;;;;;;;;;;;;; showtime
|
||||||
|
|
||||||
|
@ -112,13 +108,10 @@
|
||||||
|
|
||||||
(define (loop)
|
(define (loop)
|
||||||
(set! momentary-layer #f)
|
(set! momentary-layer #f)
|
||||||
(free! (let ((keys-pressed (vector 0 0 0 0 0 0 0)))
|
;; scanning the matrix tells us only which physical keys were pressed and
|
||||||
;; scanning the matrix tells us only which physical keys were
|
;; how many; it doesn't tell us which keycodes to send yet.
|
||||||
;; pressed and how many; it doesn't tell us which keycodes to
|
(free! (let ((keys-scanned (debounce-matrix)))
|
||||||
;; send yet.
|
(apply usb-send (keycodes-for keys-scanned (vector 0 0 0 0 0 0 0)))))
|
||||||
(let ((key-count (debounce-matrix keys-pressed 1 debounce-passes)))
|
|
||||||
(apply usb-send (keycodes-for keys-pressed (- key-count 1)
|
|
||||||
(vector 0 0 0 0 0 0 0))))))
|
|
||||||
(loop))
|
(loop))
|
||||||
|
|
||||||
(init)
|
(init)
|
||||||
|
|
4
test.rkt
4
test.rkt
|
@ -51,7 +51,7 @@
|
||||||
;; another single key
|
;; another single key
|
||||||
((2) . (0 ,key-e 0 0 0 0 0))
|
((2) . (0 ,key-e 0 0 0 0 0))
|
||||||
;; multiple normal keys
|
;; multiple normal keys
|
||||||
((2 3) . (0 ,key-e ,key-r 0 0 0 0))
|
((2 3) . (0 ,key-r ,key-e 0 0 0 0))
|
||||||
;; modifier keys (ctrl)
|
;; modifier keys (ctrl)
|
||||||
((27) . (1 0 0 0 0 0 0))
|
((27) . (1 0 0 0 0 0 0))
|
||||||
;; two modifiers (shift+ctrl) get ORed together
|
;; two modifiers (shift+ctrl) get ORed together
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
;; modifier (shift) and normal key
|
;; modifier (shift) and normal key
|
||||||
((36 4) . (2 ,key-t 0 0 0 0 0))
|
((36 4) . (2 ,key-t 0 0 0 0 0))
|
||||||
;; modifier and multiple normal keys
|
;; modifier and multiple normal keys
|
||||||
((36 4 6) . (2 ,key-t ,key-y 0 0 0 0))
|
((36 4 6) . (2 ,key-y ,key-t 0 0 0 0))
|
||||||
;; fn key alone
|
;; fn key alone
|
||||||
((40) . (0 0 0 0 0 0 0))
|
((40) . (0 0 0 0 0 0 0))
|
||||||
;; fn key and normal key
|
;; fn key and normal key
|
||||||
|
|
Loading…
Reference in a new issue