From 5b0d2c2a415ebdfe12d85b9308e0ef22799a87bf Mon Sep 17 00:00:00 2001 From: Phil Hagelberg Date: Mon, 1 Jul 2019 22:27:33 -0700 Subject: [PATCH] Rearrange, comment. --- menelaus.scm | 48 +++++++++++++++++++++++++++++------------------- test.rkt | 24 +++++++++++++++++------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/menelaus.scm b/menelaus.scm index 0713ba1..d1a5790 100644 --- a/menelaus.scm +++ b/menelaus.scm @@ -6,23 +6,14 @@ (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 max-keys 6) +(define max-keys 6) ; a single USB frame can only send 6 keycodes plus modifiers -(define (init) - (for-each-vector output row-pins) - (for-each-vector high row-pins) - (for-each-vector input column-pins) - (for-each-vector high column-pins) ; activate pullup resistors - - (call-c-func "usb_init") - (pause 200)) + +;;; matrix (define (offset-for row col) (+ col (* row (length columns)))) -(define (usb-send modifiers key1 key2 key3 key4 key5 key6) - (call-c-func "usb_send" modifiers key1 key2 key3 key4 key5 key6)) - (define (scan-key keys-pressed key-count row col) ;; pullup resistors mean a closed circuit is low rather than high (if (low? (vector-ref column-pins col)) @@ -36,7 +27,8 @@ (define (scan-column keys-pressed key-count row columns-left) (if (= (length columns-left) 0) key-count - (let ((key-count (scan-key keys-pressed key-count row (car columns-left)))) + (let ((key-count (scan-key keys-pressed key-count + row (car columns-left)))) (scan-column keys-pressed key-count row (cdr columns-left))))) (define (activate-row row) @@ -51,18 +43,19 @@ (car rows-left) columns))) (scan-matrix keys-pressed key-count (cdr rows-left))))) -(define (layout-lookup key-position) - (vector-ref layout key-position)) + +;;; layout -(define (keycode-for keys-pressed key-count keycodes) - (let ((code (vector-ref layout (vector-ref keys-pressed key-count)))) - ;; (printf "keycode ~s ~s~n" code key-count) +(define (keycode-for keys-pressed which-key keycodes) + (let ((code (vector-ref layout (vector-ref keys-pressed which-key)))) + ;; (printf "keycode ~s ~s~n" code which-key) (if (modifier? code) (begin (vector-set! keycodes 0 (+ (vector-ref keycodes 0) (unmodify code))) #f) code))) +;; translate key numbers into specific USB keycodes (define (keycodes-for keys-pressed key-count keycodes) (if (= 0 key-count) (vector->list keycodes) @@ -72,13 +65,30 @@ #f) (keycodes-for keys-pressed (- key-count 1) keycodes)))) + +;;; showtime + +(define (init) + (for-each-vector output row-pins) + (for-each-vector high row-pins) + (for-each-vector input column-pins) + (for-each-vector high column-pins) ; activate pullup resistors + + (call-c-func "usb_init") + (pause 200)) + +(define (usb-send modifiers key1 key2 key3 key4 key5 key6) + (call-c-func "usb_send" modifiers key1 key2 key3 key4 key5 key6)) + (define (loop) (free! (let ((keys-pressed (vector 0 0 0 0 0 0 0))) + ;; scanning the matrix tells us only which physical keys were + ;; pressed and how many; it doesn't tell us which keycodes to + ;; send yet. (let ((key-count (scan-matrix keys-pressed 1 rows))) (apply usb-send (keycodes-for keys-pressed (- key-count 1) (vector 0 0 0 0 0 0 0)))))) (loop)) -;;; showtime! (init) (loop) diff --git a/test.rkt b/test.rkt index b0f8233..994c4ec 100644 --- a/test.rkt +++ b/test.rkt @@ -1,24 +1,29 @@ #lang racket +;; this file simulates the hardware necessary to test the keyboard firmware, +;; because doing actual development on an atmega32u4 is nightmarishly tedious. + (define pins (make-vector 20)) (define keys (make-vector 44 #f)) -(define output void) +(define output void) ; don't bother to simulate pin modes (define input void) (define pause void) (define (high pin) (vector-set! pins pin #t)) (define (low pin) (vector-set! pins pin #f)) +;; microscheme has this as a separate form but it's just for (define (for-each-vector f v) (for ([x v]) (f x))) -(define last-usb-frame #f) +(define last-usb-frame #f) ; save this off so we can test it (define (call-c-func f-name . args) ;; (printf "FFI ~s~n" args) (set! last-usb-frame args)) (define (active-row) + ;; hypothetically we could have multiple active rows but we just assume one (for/first ([pin row-pins] [row (range (length rows))] #:when (not (vector-ref pins pin))) @@ -48,24 +53,29 @@ (define test-data (make-test-data)) -(define failures 0) +(define failures '()) (define (fail expected actual) - (set! failures (add1 failures)) - (printf "Expected ~s, got ~s~n" expected actual)) + (printf "F") + (set! failures + (cons (format "Expected ~s, got ~s~n" expected actual) failures))) + +(define (finish) + (printf (string-join failures "~n" #:before-first "~n" #:after-last "~n")) + (exit (if (empty? failures) 0 1))) ;; we can perform our checks here and make changes to the pin state. (define-syntax free! (syntax-rules () [(free! body) (if (empty? test-data) - (exit (if (= 0 failures) 0 1)) + (finish) (let ([test-case (car test-data)]) (for ([i (vector-length keys)]) (vector-set! keys i (and (member i (car test-case)) #t))) body (if (equal? (cdr test-case) last-usb-frame) - (printf ".~n") + (printf ".") (fail (cdr test-case) last-usb-frame)) (set! test-data (cdr test-data))))]))