git.s-ol.nu hw/0x33.board/firmware / 5a20a1c
add board revision abstraction s-ol a month ago
4 changed file(s) with 159 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
00 # import test
11 from hex33board import Keyboard
2 import hex33board.boards.r2_defcd99 as board
23
3 k = Keyboard()
4 k = Keyboard(board)
45 k.run()
4545
4646 audio_out: PWMAudioOut
4747
48 def __init__(self):
49 self.matrix = Matrix(
50 # cols
51 [board.GP9, board.GP4, board.GP0, board.GP6, board.GP7, board.GP8],
52 # rows
53 [
54 board.GP13,
55 board.GP12,
56 board.GP11,
57 board.GP10,
58 board.GP5,
59 board.GP1,
60 board.GP2,
61 board.GP3,
62 board.GP22,
63 ],
64 )
65
66 self.pixels = NeoPixel(board.GP17, 48 + 4, auto_write=False)
48 def __init__(self, board):
49 self.matrix = board.matrix
50
51 self.pixels = NeoPixel(board.pixels_pin, 48 + 4, auto_write=False)
6752
6853 displayio.release_displays()
69 i2c = I2C(sda=board.GP14, scl=board.GP15, frequency=1000000)
54 i2c = I2C(**board.display_pins, frequency=1000000)
7055 bus = I2CDisplay(i2c, device_address=0x3C)
7156 self.display = SSD1306(
7257 bus, width=128, height=32, rotation=180, auto_refresh=False
7459 self.display.show(displayio.Group())
7560 self.display.refresh()
7661
77 trs = UART(tx=board.GP16, rx=None, baudrate=31250)
62 trs = UART(**board.midi_pins, baudrate=31250)
7863 self.midi_trs = MIDI(None, trs)
7964
8065 midi_in = next(p for p in usb_midi.ports if isinstance(p, usb_midi.PortIn))
8166 midi_out = next(p for p in usb_midi.ports if isinstance(p, usb_midi.PortOut))
8267 self.midi_usb = MIDI(midi_in, midi_out)
8368
84 self.audio_out = PWMAudioOut(left_channel=board.GP18, right_channel=board.GP19)
85 self.i2c_in = I2C(sda=board.GP20, scl=board.GP21, frequency=1000000)
86 self.test_file = WaveFile(open("test.wav", "rb"))
69 self.audio_out = PWMAudioOut(**board.audio_pins)
8770
8871 self.settings = Settings(
8972 {
197180 elif name == 'gerhard':
198181 self.layout = GerhardLayout(offset)
199182 self.modes["base"].update_scale()
200 self.audio_out.play(self.test_file)
201183
202184 def on_scale(self, v):
203185 name = self.settings.get('scale_name').value
0 from __future__ import annotations
1
2 import board
3 from digitalio import DigitalInOut, Pull
4 from ..matrix import mapping_left_right
5
6 class Matrix:
7 '''
8 A Scanner for Keyboard Matrices with Diodes in both directions.
9
10 In a bidirectional matrix, each (col, row) crossing can be used twice -
11 once with a ROW2COL diode ("A"), and once with a COL2ROW diode ("B").
12
13 The raw key numbers returned by this scanner are based on this layout ("up_down"):
14
15 C1 C2 C3
16 +-----------
17 R1| A0 A1 A2
18 R2| A3 A4 A5
19 +-----------
20 R1| B6 B7 B8
21 R1| B9 B10 B11
22
23 If the physical layout of the matrix is different, you can pass a function
24 for `mapping`. The function is passed `len_cols` and `len_rows` and should
25 return a `coord_mapping` list.
26 Various common mappings are provided in this module, see:
27 - `kmk.scanners.bidirectional.mapping_left_right`
28 - `kmk.scanners.bidirectional.mapping_left_right_mirrored`
29 - `kmk.scanners.bidirectional.mapping_up_down`
30 - `kmk.scanners.bidirectional.mapping_up_down_mirrored`
31 - `kmk.scanners.bidirectional.mapping_interleave_rows`
32 - `kmk.scanners.bidirectional.mapping_interleave_cols`
33
34 :param cols: A sequence of pins that are the columns for matrix A.
35 :param rows: A sequence of pins that are the rows for matrix A.
36 :param mapping: A coord_mapping generator function, see above.
37 '''
38
39 def __init__(self, cols, rows, mapping=mapping_left_right):
40 self.len_cols = len(cols)
41 self.len_rows = len(rows)
42 self.half_size = self.len_cols * self.len_rows
43 self.keys = self.half_size * 2
44
45 self.coord_mapping = mapping(self.len_cols, self.len_rows)
46
47 # A pin cannot be both a row and column, detect this by combining the
48 # two tuples into a set and validating that the length did not drop
49 #
50 # repr() hackery is because CircuitPython Pin objects are not hashable
51 unique_pins = {repr(c) for c in cols} | {repr(r) for r in rows}
52 assert (
53 len(unique_pins) == self.len_cols + self.len_rows
54 ), 'Cannot use a pin as both a column and row'
55 del unique_pins
56
57 # __class__.__name__ is used instead of isinstance as the MCP230xx lib
58 # does not use the digitalio.DigitalInOut, but rather a self defined one:
59 # https://github.com/adafruit/Adafruit_CircuitPython_MCP230xx/blob/3f04abbd65ba5fa938fcb04b99e92ae48a8c9406/adafruit_mcp230xx/digital_inout.py#L33
60
61 self.cols = [
62 x if x.__class__.__name__ == 'DigitalInOut' else DigitalInOut(x)
63 for x in cols
64 ]
65 self.rows = [
66 x if x.__class__.__name__ == 'DigitalInOut' else DigitalInOut(x)
67 for x in rows
68 ]
69
70 self.state = bytearray(self.keys)
71
72 def scan_for_changes(self):
73 for (inputs, outputs, flip) in [
74 (self.rows, self.cols, False),
75 (self.cols, self.rows, True),
76 ]:
77 for pin in outputs:
78 pin.switch_to_input()
79
80 for pin in inputs:
81 pin.switch_to_input(pull=Pull.DOWN)
82
83 for oidx, opin in enumerate(outputs):
84 opin.switch_to_output(value=True)
85
86 for iidx, ipin in enumerate(inputs):
87 if flip:
88 ba_idx = oidx * len(inputs) + iidx + self.half_size
89 else:
90 ba_idx = iidx * len(outputs) + oidx
91
92 # cast to int to avoid
93 #
94 # >>> xyz = bytearray(3)
95 # >>> xyz[2] = True
96 # Traceback (most recent call last):
97 # File "<stdin>", line 1, in <module>
98 # OverflowError: value would overflow a 1 byte buffer
99 #
100 # I haven't dived too far into what causes this, but it's
101 # almost certainly because bool types in Python aren't just
102 # aliases to int values, but are proper pseudo-types
103 new_val = int(ipin.value)
104 old_val = self.state[ba_idx]
105
106 if old_val != new_val:
107 self.state[ba_idx] = new_val
108 yield self.coord_mapping.index(ba_idx), new_val
109
110 opin.switch_to_input()
111
112 matrix = Matrix(
113 [board.GP8, board.GP4, board.GP0, board.GP6, board.GP7, board.GP9],
114 [board.GP5, board.GP1, board.GP2, board.GP3, board.GP10],
115 )
116
117 pixels_pin = board.GP11
118 display_pins = { "sda": board.GP14, "scl": board.GP15 }
119
120 midi_pins = { "tx": board.GP16, "rx": None }
121 audio_pins = { "left_channel": board.GP12, "right_channel": board.GP13 }
122 i2c_pins = None
0 import board
1
2 from ..matrix import Matrix
3
4 matrix = Matrix(
5 # cols
6 [board.GP9, board.GP4, board.GP0, board.GP6, board.GP7, board.GP8],
7 # rows
8 [
9 board.GP13,
10 board.GP12,
11 board.GP11,
12 board.GP10,
13 board.GP5,
14 board.GP1,
15 board.GP2,
16 board.GP3,
17 board.GP22,
18 ],
19 )
20
21 pixels_pin = board.GP17
22 display_pins = { "sda": board.GP14, "scl": board.GP15 }
23
24 midi_pins = { "tx": board.GP16, "rx": None }
25 audio_pins = { "left_channel": board.GP18, "right_channel": board.GP19 }
26 i2c_pins = { "sda": board.GP20, "scl": board.GP21 }