Skip to content

Instantly share code, notes, and snippets.

@mathias
Created October 14, 2021 15:35
Show Gist options
  • Save mathias/e4a60bff162e909857c677177f23ef64 to your computer and use it in GitHub Desktop.
Save mathias/e4a60bff162e909857c677177f23ef64 to your computer and use it in GitHub Desktop.
how keyboard firmwares work in Ruby psuedo-code
# Step 1: A single key
require 'board'
## A key = row 2, pin 11
board.setInput(11) # Pin 11
board.setHigh(11) # Activate pullup resistor
# Set rows 0-3 outputs, and high:
[0, 1, 2, 3].each do |row|
board.setOutput(row)
board.setHigh(row)
end
# Set our row as low (ready to receive input)
board.SetLow(2)
call_c_func("usb_init")
sleep 0.2
while true do
if board.low?(11)
call_c_func("usb_send", 0, 4, 0, 0, 0, 0, 0)
call_c_func("usb_send", 0, 0, 0, 0, 0, 0, 0)
end
end
# It feels a bit backwards to treat high as deactivated and low as activated, but beacuse of the pullup resistors built-in to eac pin, this is the most convenient way to detect switch state. If it helps, you can think of "high" as having the key be in its "up" position and "low" as being pressed down, but of course this is not the actual reason.
# Step 2: A full row
require 'board'
require 'keycodes'
include Keycodes
# Teensy pins
@column_pins = [11, 12, 18, 19, 10, 7, 8, 9, 5, 6]
@layout = [KEY_A, KEY_S, KEY_D, KEY_F, KEY_G,
KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON]
# Set rows 0-3 outputs, and high:
[0..3].each do |row|
board.setOutput(row)
board.setHigh(row)
end
# Set row as low (ready to receive input)
board.SetLow(2)
@column_pins.each do |col_pin|
board.setInput(col_pin)
board.setHigh(col_pin) # Activate pullup resistor
end
call_c_func("usb_init")
sleep 0.2
def scan_column(col_pin, index)
if board.low?(col_pin)
code = @layout[index]
call_c_func("usb_send", 0, code, 0, 0, 0, 0, 0)
end
end
while true do
@column_pins.each_with_index do |col, index|
scan_column(col, index)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment