Rearrange, comment.

This commit is contained in:
Phil Hagelberg 2019-07-01 22:27:33 -07:00
parent 6ded72a729
commit 5b0d2c2a41
2 changed files with 46 additions and 26 deletions

View file

@ -6,23 +6,14 @@
(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) (define max-keys 6) ; a single USB frame can only send 6 keycodes plus modifiers
(define (init)
(for-each-vector output row-pins) ;;; matrix
(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 (offset-for row col) (define (offset-for row col)
(+ col (* row (length columns)))) (+ 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) (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))
@ -36,7 +27,8 @@
(define (scan-column keys-pressed key-count row columns-left) (define (scan-column keys-pressed key-count row columns-left)
(if (= (length columns-left) 0) (if (= (length columns-left) 0)
key-count 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))))) (scan-column keys-pressed key-count row (cdr columns-left)))))
(define (activate-row row) (define (activate-row row)
@ -51,18 +43,19 @@
(car rows-left) columns))) (car rows-left) columns)))
(scan-matrix keys-pressed key-count (cdr rows-left))))) (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) (define (keycode-for keys-pressed which-key keycodes)
(let ((code (vector-ref layout (vector-ref keys-pressed key-count)))) (let ((code (vector-ref layout (vector-ref keys-pressed which-key))))
;; (printf "keycode ~s ~s~n" code key-count) ;; (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)
(unmodify code))) (unmodify code)))
#f) #f)
code))) code)))
;; translate key numbers into specific USB keycodes
(define (keycodes-for keys-pressed key-count keycodes) (define (keycodes-for keys-pressed key-count keycodes)
(if (= 0 key-count) (if (= 0 key-count)
(vector->list keycodes) (vector->list keycodes)
@ -72,13 +65,30 @@
#f) #f)
(keycodes-for keys-pressed (- key-count 1) keycodes)))) (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) (define (loop)
(free! (let ((keys-pressed (vector 0 0 0 0 0 0 0))) (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))) (let ((key-count (scan-matrix keys-pressed 1 rows)))
(apply usb-send (keycodes-for keys-pressed (- key-count 1) (apply usb-send (keycodes-for keys-pressed (- key-count 1)
(vector 0 0 0 0 0 0 0)))))) (vector 0 0 0 0 0 0 0))))))
(loop)) (loop))
;;; showtime!
(init) (init)
(loop) (loop)

View file

@ -1,24 +1,29 @@
#lang racket #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 pins (make-vector 20))
(define keys (make-vector 44 #f)) (define keys (make-vector 44 #f))
(define output void) (define output void) ; don't bother to simulate pin modes
(define input void) (define input void)
(define pause void) (define pause void)
(define (high pin) (vector-set! pins pin #t)) (define (high pin) (vector-set! pins pin #t))
(define (low pin) (vector-set! pins pin #f)) (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 (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) (define (call-c-func f-name . args)
;; (printf "FFI ~s~n" args) ;; (printf "FFI ~s~n" args)
(set! last-usb-frame args)) (set! last-usb-frame args))
(define (active-row) (define (active-row)
;; hypothetically we could have multiple active rows but we just assume one
(for/first ([pin row-pins] (for/first ([pin row-pins]
[row (range (length rows))] [row (range (length rows))]
#:when (not (vector-ref pins pin))) #:when (not (vector-ref pins pin)))
@ -48,24 +53,29 @@
(define test-data (make-test-data)) (define test-data (make-test-data))
(define failures 0) (define failures '())
(define (fail expected actual) (define (fail expected actual)
(set! failures (add1 failures)) (printf "F")
(printf "Expected ~s, got ~s~n" expected actual)) (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. ;; we can perform our checks here and make changes to the pin state.
(define-syntax free! (define-syntax free!
(syntax-rules () (syntax-rules ()
[(free! body) (if (empty? test-data) [(free! body) (if (empty? test-data)
(exit (if (= 0 failures) 0 1)) (finish)
(let ([test-case (car test-data)]) (let ([test-case (car test-data)])
(for ([i (vector-length keys)]) (for ([i (vector-length keys)])
(vector-set! keys i (vector-set! keys i
(and (member i (car test-case)) #t))) (and (member i (car test-case)) #t)))
body body
(if (equal? (cdr test-case) last-usb-frame) (if (equal? (cdr test-case) last-usb-frame)
(printf ".~n") (printf ".")
(fail (cdr test-case) last-usb-frame)) (fail (cdr test-case) last-usb-frame))
(set! test-data (cdr test-data))))])) (set! test-data (cdr test-data))))]))