Rearrange, comment.
This commit is contained in:
parent
6ded72a729
commit
5b0d2c2a41
2 changed files with 46 additions and 26 deletions
48
menelaus.scm
48
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)
|
||||
|
|
24
test.rkt
24
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))))]))
|
||||
|
||||
|
|
Loading…
Reference in a new issue