concertina

Elecronic concertina
git clone https://git.woozle.org/neale/concertina.git

commit
a5cef60
parent
3da6c33
author
Neale Pickett
date
2026-02-10 14:24:02 -0700 MST
Let's try my old pal, attiny85
10 files changed,  +79, -485
M .gitignore
+8, -4
 1@@ -1,5 +1,9 @@
 2-*.stl
 3-*.3mf
 4+pcb/*
 5+
 6+3d/*.stl
 7+3d/*.3mf
 8+
 9 src/layouts.h
10-pcb/*-backups/
11-build/
12+src/*.o
13+src/*.hex
14+src/*.elf
D Makefile
+0, -33
 1@@ -1,33 +0,0 @@
 2-ARDUINO_DIR = /app/Arduino
 3-BUILDER = flatpak run --command=${ARDUINO_DIR}/arduino-builder cc.arduino.arduinoide
 4-
 5-flash: flash-itsybitsy
 6-flash-itsybitsy: build/itsybitsy_m0/concertina.ino.bin
 7-	stty -F /dev/ttyACM0 1200 && sleep 1 # Reset into bootloader
 8-	bossac --offset=0x2000 -w -v $< -R
 9-
10-build: build/itsybitsy_m0/concertina.ino.bin
11-
12-clean:
13-	rm -rf build/*
14-
15-layouts.h: layouts.txt mklayouts.py
16-	./mklayouts.py $< > $@
17-
18-build/itsybitsy_m0/%.ino.bin: FQBN = adafruit:samd:adafruit_itsybitsy_m0
19-build/%/concertina.ino.bin: concertina.ino layouts.h
20-	mkdir -p build/$*
21-	$(BUILDER) \
22-		-build-cache ~/.cache/arduino \
23-		-build-path build/$* \
24-		-core-api-version 10813 \
25-		-fqbn $(FQBN) \
26-		-hardware ~/.arduino15/packages \
27-		-tools $(ARDUINO_DIR)/tools-builder \
28-		-tools ~/.arduino15/packages \
29-		-hardware $(ARDUINO_DIR)/hardware \
30-		-hardware ~/.arduino15/packages \
31-		-built-in-libraries $(ARDUINO_DIR)/libraries \
32-		-libraries ~/Arduino/libraries \
33-		-compile \
34-		$<
D lato-8.h
+0, -180
  1@@ -1,180 +0,0 @@
  2-const uint8_t Lato8Bitmaps[] PROGMEM = {
  3-  0xfe, 0x20, 0xb6, 0xd0, 0x12, 0x24, 0x24, 0xff, 0x24, 0x24, 0x48, 0xfe,
  4-  0x48, 0x48, 0x48, 0x10, 0x20, 0xf2, 0x99, 0x0a, 0x1c, 0x0e, 0x12, 0x24,
  5-  0x4c, 0xb7, 0xc2, 0x04, 0x00, 0x70, 0x52, 0x12, 0x24, 0x49, 0x07, 0x40,
  6-  0x0b, 0x82, 0x90, 0x91, 0x22, 0x48, 0x38, 0x3c, 0x08, 0x84, 0x21, 0x00,
  7-  0x20, 0x14, 0x08, 0x8a, 0x1c, 0x81, 0x31, 0xa7, 0x8c, 0xf0, 0x29, 0x49,
  8-  0x24, 0x92, 0x24, 0x40, 0x89, 0x12, 0x49, 0x24, 0xa5, 0x00, 0x25, 0xd9,
  9-  0xf2, 0x00, 0x10, 0x20, 0x47, 0xf1, 0x02, 0x04, 0x00, 0x58, 0xf0, 0x80,
 10-  0x08, 0x44, 0x21, 0x10, 0x88, 0x44, 0x21, 0x00, 0x3c, 0x46, 0x82, 0x81,
 11-  0x81, 0x81, 0x81, 0x81, 0x82, 0x46, 0x3c, 0x31, 0x49, 0x04, 0x10, 0x41,
 12-  0x04, 0x10, 0x4f, 0xc0, 0x3c, 0x8e, 0x08, 0x10, 0x20, 0x82, 0x08, 0x20,
 13-  0x83, 0xf8, 0x3c, 0x8e, 0x08, 0x10, 0x43, 0x80, 0x81, 0x83, 0x8d, 0xf0,
 14-  0x02, 0x03, 0x02, 0x82, 0x42, 0x21, 0x11, 0x09, 0xff, 0x02, 0x01, 0x00,
 15-  0x80, 0x3e, 0x81, 0x02, 0x07, 0xc0, 0xc0, 0x81, 0x03, 0x09, 0xe0, 0x0c,
 16-  0x10, 0x41, 0x07, 0xc8, 0x60, 0xc1, 0x82, 0x84, 0xf0, 0xff, 0x02, 0x02,
 17-  0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x3c, 0x8e, 0x0c, 0x14,
 18-  0x47, 0x90, 0xc1, 0x83, 0x85, 0xf0, 0x3c, 0x8e, 0x0c, 0x1c, 0x6f, 0x81,
 19-  0x04, 0x10, 0x20, 0x80, 0x82, 0x40, 0x01, 0x80, 0x04, 0x66, 0x30, 0x60,
 20-  0x60, 0x40, 0xfe, 0x03, 0xf8, 0x81, 0x81, 0x83, 0x19, 0x88, 0x00, 0x74,
 21-  0x42, 0x11, 0x10, 0x84, 0x00, 0x08, 0x0f, 0x06, 0x19, 0x00, 0xc0, 0x18,
 22-  0x73, 0x12, 0x64, 0x4c, 0x89, 0x93, 0x31, 0xb9, 0x00, 0x18, 0x30, 0xf8,
 23-  0x04, 0x03, 0x00, 0xa0, 0x48, 0x11, 0x08, 0x42, 0x10, 0xfe, 0x40, 0x90,
 24-  0x18, 0x04, 0xf9, 0x0a, 0x0c, 0x18, 0x5f, 0x21, 0xc1, 0x83, 0x07, 0xf0,
 25-  0x1f, 0x30, 0x50, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x40, 0x30, 0x47,
 26-  0xc0, 0xfc, 0x41, 0xa0, 0x50, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x81, 0x41,
 27-  0xbf, 0x00, 0xfe, 0x08, 0x20, 0x83, 0xe8, 0x20, 0x82, 0x0f, 0xc0, 0xfe,
 28-  0x08, 0x20, 0x83, 0xf8, 0x20, 0x82, 0x08, 0x00, 0x1f, 0x18, 0x34, 0x02,
 29-  0x00, 0x80, 0x20, 0x08, 0x1e, 0x01, 0x40, 0x58, 0x31, 0xf0, 0x81, 0x81,
 30-  0x81, 0x81, 0x81, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0xff, 0xe0, 0x08,
 31-  0x42, 0x10, 0x84, 0x21, 0x08, 0xfc, 0x83, 0x84, 0x88, 0x90, 0xa0, 0xe0,
 32-  0xb0, 0x98, 0x8c, 0x86, 0x83, 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x82,
 33-  0x0f, 0xc0, 0x80, 0x30, 0x0f, 0x02, 0xd0, 0x5a, 0x13, 0x22, 0x64, 0x8c,
 34-  0x51, 0x84, 0x30, 0x06, 0x00, 0x80, 0x81, 0x81, 0xc1, 0xa1, 0x91, 0x89,
 35-  0x89, 0x85, 0x83, 0x81, 0x81, 0x1f, 0x0c, 0x11, 0x01, 0x40, 0x28, 0x03,
 36-  0x00, 0x60, 0x0c, 0x02, 0x40, 0x4c, 0x10, 0x7c, 0x00, 0xf9, 0x0a, 0x0c,
 37-  0x18, 0x30, 0xbe, 0x40, 0x81, 0x02, 0x00, 0x1f, 0x0c, 0x11, 0x01, 0x40,
 38-  0x28, 0x03, 0x00, 0x60, 0x0c, 0x02, 0x40, 0x4c, 0x10, 0x7e, 0x00, 0x40,
 39-  0x04, 0x00, 0x40, 0xf9, 0x0a, 0x0c, 0x28, 0x5f, 0x24, 0x44, 0x89, 0x0a,
 40-  0x08, 0x38, 0x8a, 0x04, 0x06, 0x03, 0x01, 0x01, 0x03, 0x09, 0xe0, 0xff,
 41-  0x84, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
 42-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xc2, 0x3c, 0x80,
 43-  0x50, 0x14, 0x08, 0x82, 0x21, 0x08, 0x41, 0x10, 0x48, 0x0a, 0x03, 0x00,
 44-  0x40, 0x80, 0x81, 0x41, 0x82, 0x41, 0x82, 0x42, 0x42, 0x22, 0x42, 0x22,
 45-  0x24, 0x24, 0x24, 0x14, 0x24, 0x14, 0x18, 0x18, 0x18, 0x08, 0x10, 0xc0,
 46-  0xc8, 0x42, 0x10, 0x48, 0x0c, 0x03, 0x00, 0xc0, 0x48, 0x21, 0x10, 0x2c,
 47-  0x0c, 0x80, 0xa0, 0x88, 0x44, 0x41, 0x20, 0x60, 0x20, 0x10, 0x08, 0x04,
 48-  0x02, 0x00, 0xff, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x80,
 49-  0xff, 0xea, 0xaa, 0xaa, 0xb0, 0x84, 0x20, 0x84, 0x10, 0x82, 0x10, 0x82,
 50-  0x10, 0xd5, 0x55, 0x55, 0x70, 0x10, 0x50, 0xa2, 0x2c, 0x60, 0xfe, 0x90,
 51-  0x7a, 0x20, 0x5f, 0x86, 0x18, 0xfd, 0x81, 0x02, 0x05, 0xec, 0x50, 0x60,
 52-  0xc1, 0x83, 0x8a, 0xe0, 0x7b, 0x18, 0x20, 0x82, 0x0c, 0x5e, 0x02, 0x04,
 53-  0x0b, 0xdc, 0x70, 0x60, 0xc1, 0x83, 0x8d, 0xe8, 0x79, 0x8a, 0x0f, 0xf8,
 54-  0x10, 0x11, 0x1c, 0x19, 0x09, 0xf2, 0x10, 0x84, 0x21, 0x08, 0x7f, 0x12,
 55-  0x14, 0x27, 0x90, 0x20, 0x3e, 0x83, 0x09, 0xe0, 0x81, 0x02, 0x05, 0xec,
 56-  0x50, 0x60, 0xc1, 0x83, 0x06, 0x08, 0x9f, 0xe0, 0x20, 0x12, 0x49, 0x24,
 57-  0x93, 0x80, 0x82, 0x08, 0x21, 0x9a, 0x8e, 0x28, 0x92, 0x28, 0x40, 0xff,
 58-  0xe0, 0xb9, 0xd9, 0x4a, 0x10, 0xc2, 0x18, 0x43, 0x08, 0x61, 0x0c, 0x21,
 59-  0xbd, 0x8a, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0x79, 0x8a, 0x0c, 0x18, 0x30,
 60-  0x71, 0x3c, 0xbd, 0x8a, 0x0c, 0x18, 0x30, 0x71, 0x5c, 0x81, 0x02, 0x00,
 61-  0x7b, 0x8e, 0x0c, 0x18, 0x30, 0x71, 0xbd, 0x02, 0x04, 0x08, 0xbc, 0x88,
 62-  0x88, 0x88, 0x74, 0x60, 0xc1, 0x86, 0x2e, 0x21, 0x09, 0xf2, 0x10, 0x84,
 63-  0x21, 0x4e, 0x86, 0x18, 0x61, 0x86, 0x1c, 0x5f, 0x81, 0x42, 0x42, 0x24,
 64-  0x24, 0x14, 0x18, 0x18, 0x82, 0x14, 0x62, 0x46, 0x24, 0x92, 0x29, 0x42,
 65-  0x94, 0x30, 0xc1, 0x08, 0xc2, 0x88, 0xa0, 0xc1, 0x85, 0x11, 0x61, 0x81,
 66-  0x42, 0x42, 0x24, 0x24, 0x14, 0x18, 0x08, 0x10, 0x10, 0x20, 0xfc, 0x21,
 67-  0x08, 0x21, 0x08, 0x3f, 0x72, 0x44, 0xa2, 0x4a, 0x48, 0xc0, 0xff, 0xfe,
 68-  0xc4, 0x94, 0x8a, 0x48, 0x93, 0x80, 0x73, 0x18, 0x11, 0x11, 0x11, 0x11,
 69-  0x7f, 0xe0, 0x08, 0x40, 0x21, 0x86, 0x18, 0x61, 0xc5, 0xf0, 0x84, 0x21,
 70-  0x0b, 0x6e, 0x73, 0xb6, 0x00, 0x92, 0xfb, 0x6f, 0xa4, 0x80, 0x12, 0x94,
 71-  0xb7, 0x69, 0x4b, 0x76, 0x94, 0xa4, 0x00
 72-};
 73-
 74-const GFXglyph Lato8Glyphs[] PROGMEM = {
 75-  {  794,    6,   10,    6,    0,   -9 }, // 0x15 'ú'
 76-  {  788,    4,   11,    6,    1,  -10 }, // 0x16 '♩'
 77-  {  802,    5,   10,    7,    1,   -9 }, // 0x17 '♭'
 78-  {  809,    3,   11,    5,    1,  -10 }, // 0x18 '♮'
 79-  {  814,    5,   13,    7,    1,  -11 }, // 0x19 '♯'
 80-  {    0,    0,    0,    3,    0,  -12 }, // 0x20 ' '
 81-  {    0,    1,   11,    3,    1,  -10 }, // 0x21 '!'
 82-  {    2,    3,    4,    5,    1,  -10 }, // 0x22 '"'
 83-  {    4,    8,   11,    9,    1,  -10 }, // 0x23 '#'
 84-  {   15,    7,   15,    9,    1,  -12 }, // 0x24 '$'
 85-  {   29,   11,   10,   12,    1,   -9 }, // 0x25 '%'
 86-  {   43,   10,   11,   11,    1,  -10 }, // 0x26 '&'
 87-  {   57,    1,    4,    3,    1,  -10 }, // 0x27 '''
 88-  {   58,    3,   14,    4,    1,  -11 }, // 0x28 '('
 89-  {   64,    3,   14,    5,    1,  -11 }, // 0x29 ')'
 90-  {   70,    5,    5,    7,    1,  -11 }, // 0x2a '*'
 91-  {   74,    7,    7,    9,    1,   -8 }, // 0x2b '+'
 92-  {   81,    2,    3,    5,    1,    0 }, // 0x2c ','
 93-  {   82,    4,    1,    6,    1,   -4 }, // 0x2d '-'
 94-  {   83,    1,    1,    3,    1,    0 }, // 0x2e '.'
 95-  {   84,    5,   12,    7,    1,  -10 }, // 0x2f '/'
 96-  {   92,    8,   11,    9,    1,  -10 }, // 0x30 '0'
 97-  {  103,    6,   11,    9,    2,  -10 }, // 0x31 '1'
 98-  {  112,    7,   11,    9,    1,  -10 }, // 0x32 '2'
 99-  {  122,    7,   11,    9,    1,  -10 }, // 0x33 '3'
100-  {  132,    9,   11,    9,    0,  -10 }, // 0x34 '4'
101-  {  145,    7,   11,    9,    1,  -10 }, // 0x35 '5'
102-  {  155,    7,   11,    9,    1,  -10 }, // 0x36 '6'
103-  {  165,    8,   11,    9,    1,  -10 }, // 0x37 '7'
104-  {  176,    7,   11,    9,    1,  -10 }, // 0x38 '8'
105-  {  186,    7,   11,    9,    1,  -10 }, // 0x39 '9'
106-  {  196,    1,    7,    3,    1,   -6 }, // 0x3a ':'
107-  {  197,    2,    9,    4,    1,   -6 }, // 0x3b ';'
108-  {  200,    6,    7,    9,    1,   -8 }, // 0x3c '<'
109-  {  206,    7,    3,    9,    1,   -6 }, // 0x3d '='
110-  {  209,    6,    7,    9,    2,   -8 }, // 0x3e '>'
111-  {  215,    5,   11,    7,    1,  -10 }, // 0x3f '?'
112-  {  222,   11,   13,   13,    1,  -10 }, // 0x40 '@'
113-  {  240,   10,   11,   10,    0,  -10 }, // 0x41 'A'
114-  {  254,    7,   11,   10,    2,  -10 }, // 0x42 'B'
115-  {  264,    9,   11,   11,    1,  -10 }, // 0x43 'C'
116-  {  277,    9,   11,   12,    2,  -10 }, // 0x44 'D'
117-  {  290,    6,   11,    9,    2,  -10 }, // 0x45 'E'
118-  {  299,    6,   11,    9,    2,  -10 }, // 0x46 'F'
119-  {  308,   10,   11,   12,    1,  -10 }, // 0x47 'G'
120-  {  322,    8,   11,   12,    2,  -10 }, // 0x48 'H'
121-  {  333,    1,   11,    4,    2,  -10 }, // 0x49 'I'
122-  {  335,    5,   11,    7,    0,  -10 }, // 0x4a 'J'
123-  {  342,    8,   11,   10,    2,  -10 }, // 0x4b 'K'
124-  {  353,    6,   11,    8,    2,  -10 }, // 0x4c 'L'
125-  {  362,   11,   11,   15,    2,  -10 }, // 0x4d 'M'
126-  {  378,    8,   11,   12,    2,  -10 }, // 0x4e 'N'
127-  {  389,   11,   11,   13,    1,  -10 }, // 0x4f 'O'
128-  {  405,    7,   11,    9,    2,  -10 }, // 0x50 'P'
129-  {  415,   11,   14,   13,    1,  -10 }, // 0x51 'Q'
130-  {  435,    7,   11,   10,    2,  -10 }, // 0x52 'R'
131-  {  445,    7,   11,    9,    1,  -10 }, // 0x53 'S'
132-  {  455,    9,   11,    9,    0,  -10 }, // 0x54 'T'
133-  {  468,    8,   11,   12,    2,  -10 }, // 0x55 'U'
134-  {  479,   10,   11,   10,    0,  -10 }, // 0x56 'V'
135-  {  493,   16,   11,   16,    0,  -10 }, // 0x57 'W'
136-  {  515,   10,   11,   10,    0,  -10 }, // 0x58 'X'
137-  {  529,    9,   11,   10,    0,  -10 }, // 0x59 'Y'
138-  {  542,    8,   11,   10,    1,  -10 }, // 0x5a 'Z'
139-  {  553,    2,   14,    5,    2,  -11 }, // 0x5b '['
140-  {  557,    5,   12,    7,    1,  -10 }, // 0x5c '\'
141-  {  565,    2,   14,    5,    1,  -11 }, // 0x5d ']'
142-  {  569,    7,    5,    9,    1,  -10 }, // 0x5e '^'
143-  {  574,    7,    1,    7,    0,    2 }, // 0x5f '_'
144-  {  575,    2,    2,    6,    2,  -10 }, // 0x60 '`'
145-  {  576,    6,    8,    8,    1,   -7 }, // 0x61 'a'
146-  {  582,    7,   11,    9,    1,  -10 }, // 0x62 'b'
147-  {  592,    6,    8,    8,    1,   -7 }, // 0x63 'c'
148-  {  598,    7,   11,    9,    1,  -10 }, // 0x64 'd'
149-  {  608,    7,    8,    8,    1,   -7 }, // 0x65 'e'
150-  {  615,    5,   11,    5,    0,  -10 }, // 0x66 'f'
151-  {  622,    7,   11,    8,    1,   -7 }, // 0x67 'g'
152-  {  632,    7,   11,    9,    1,  -10 }, // 0x68 'h'
153-  {  642,    1,   11,    4,    1,  -10 }, // 0x69 'i'
154-  {  644,    3,   14,    4,   -1,  -10 }, // 0x6a 'j'
155-  {  650,    6,   11,    8,    1,  -10 }, // 0x6b 'k'
156-  {  659,    1,   11,    4,    1,  -10 }, // 0x6c 'l'
157-  {  661,   11,    8,   13,    1,   -7 }, // 0x6d 'm'
158-  {  672,    7,    8,    9,    1,   -7 }, // 0x6e 'n'
159-  {  679,    7,    8,    9,    1,   -7 }, // 0x6f 'o'
160-  {  686,    7,   11,    9,    1,   -7 }, // 0x70 'p'
161-  {  696,    7,   11,    9,    1,   -7 }, // 0x71 'q'
162-  {  706,    4,    8,    6,    1,   -7 }, // 0x72 'r'
163-  {  710,    5,    8,    7,    1,   -7 }, // 0x73 's'
164-  {  715,    5,   11,    5,    0,  -10 }, // 0x74 't'
165-  {  722,    6,    8,    9,    1,   -7 }, // 0x75 'u'
166-  {  728,    8,    8,    8,    0,   -7 }, // 0x76 'v'
167-  {  736,   12,    8,   12,    0,   -7 }, // 0x77 'w'
168-  {  748,    7,    8,    8,    0,   -7 }, // 0x78 'x'
169-  {  755,    8,   11,    8,    0,   -7 }, // 0x79 'y'
170-  {  766,    6,    8,    7,    1,   -7 }, // 0x7a 'z'
171-  {  772,    3,   14,    5,    1,  -11 }, // 0x7b '{'
172-  {  778,    1,   15,    4,    1,  -11 }, // 0x7c '|'
173-  {  780,    3,   14,    5,    1,  -11 }, // 0x7d '}'
174-  {  786,    7,    2,    9,    1,   -5 }, // 0x7e '~'
175-};
176-
177-const GFXfont Lato8 PROGMEM = {
178-  (uint8_t *)Lato8Bitmaps,
179-  (GFXglyph *)Lato8Glyphs,
180-  0x15, 0x7e, 19
181-};
D layouts.h
+0, -266
  1@@ -1,266 +0,0 @@
  2-/* Generated from layouts.txt by mklayouts.py */
  3-#pragma once
  4-
  5-struct layout_t {
  6-  char const *name;
  7-  int8_t notes[2][4][5][2]; /* side, row, col, push/draw */
  8-};
  9-
 10-const layout_t layouts[] = {
 11-  { "Eirú C/G",
 12-    { // sides
 13-      { // rows
 14-        { // buttons
 15-          {52, 53}, // E,/F,
 16-          {57, 58}, // A,/B_,
 17-          {61, 63}, // C^/D^
 18-          {69, 67}, // A/G
 19-          {68, 70}, // G^/B_
 20-        },
 21-        { // buttons
 22-          {48, 55}, // C,/G,
 23-          {55, 59}, // G,/B,
 24-          {60, 62}, // C/D
 25-          {64, 65}, // E/F
 26-          {67, 69}, // G/A
 27-        },
 28-        { // buttons
 29-          {59, 57}, // B,/A,
 30-          {62, 66}, // D/F^
 31-          {67, 69}, // G/A
 32-          {71, 72}, // B/c
 33-          {74, 76}, // d/e
 34-        },
 35-        { // buttons
 36-          {-1, -1}, // -
 37-          {-1, -1}, // -
 38-          {-1, -1}, // -
 39-          {-1, -1}, // -
 40-          {50, 50}, // D,/D,
 41-        },
 42-      },
 43-      { // rows
 44-        { // buttons
 45-          {73, 75}, // c^/d^
 46-          {75, 73}, // d^/c^
 47-          {80, 79}, // g^/g
 48-          {85, 82}, // c^'/b_
 49-          {81, 86}, // a/d'
 50-        },
 51-        { // buttons
 52-          {72, 71}, // c/B
 53-          {76, 74}, // e/d
 54-          {79, 77}, // g/f
 55-          {84, 81}, // c'/a
 56-          {88, 83}, // e'/b
 57-        },
 58-        { // buttons
 59-          {79, 78}, // g/f^
 60-          {83, 81}, // b/a
 61-          {86, 84}, // d'/c'
 62-          {91, 88}, // g'/e'
 63-          {87, 90}, // d^'/f^'
 64-        },
 65-        { // buttons
 66-          {-1, -1}, // -
 67-          {-1, -1}, // -
 68-          {-1, -1}, // -
 69-          {-1, -1}, // -
 70-          {-1, -1}, // -
 71-        },
 72-      },
 73-    }
 74-  },
 75-  { "Rochelle C/G",
 76-    { // sides
 77-      { // rows
 78-        { // buttons
 79-          {52, 53}, // E,/F,
 80-          {57, 58}, // A,/B_,
 81-          {61, 63}, // C^/D^
 82-          {69, 67}, // A/G
 83-          {68, 70}, // G^/B_
 84-        },
 85-        { // buttons
 86-          {48, 55}, // C,/G,
 87-          {55, 59}, // G,/B,
 88-          {60, 62}, // C/D
 89-          {64, 65}, // E/F
 90-          {67, 69}, // G/A
 91-        },
 92-        { // buttons
 93-          {59, 57}, // B,/A,
 94-          {62, 66}, // D/F^
 95-          {67, 69}, // G/A
 96-          {71, 72}, // B/c
 97-          {74, 76}, // d/e
 98-        },
 99-        { // buttons
100-          {-1, -1}, // -
101-          {-1, -1}, // -
102-          {-1, -1}, // -
103-          {-1, -1}, // -
104-          {50, 50}, // D,/D,
105-        },
106-      },
107-      { // rows
108-        { // buttons
109-          {73, 75}, // c^/d^
110-          {81, 73}, // a/c^
111-          {80, 79}, // g^/g
112-          {85, 82}, // c^'/b_
113-          {93, 86}, // a'/d'
114-        },
115-        { // buttons
116-          {72, 71}, // c/B
117-          {76, 74}, // e/d
118-          {79, 77}, // g/f
119-          {84, 81}, // c'/a
120-          {88, 83}, // e'/b
121-        },
122-        { // buttons
123-          {79, 78}, // g/f^
124-          {83, 81}, // b/a
125-          {86, 84}, // d'/c'
126-          {91, 88}, // g'/e'
127-          {95, 90}, // b'/f^'
128-        },
129-        { // buttons
130-          {-1, -1}, // -
131-          {-1, -1}, // -
132-          {-1, -1}, // -
133-          {-1, -1}, // -
134-          {-1, -1}, // -
135-        },
136-      },
137-    }
138-  },
139-  { "Jeffries C/G",
140-    { // sides
141-      { // rows
142-        { // buttons
143-          {52, 53}, // E,/F,
144-          {57, 58}, // A,/B_,
145-          {61, 63}, // C^/D^
146-          {69, 67}, // A/G
147-          {68, 70}, // G^/B_
148-        },
149-        { // buttons
150-          {48, 55}, // C,/G,
151-          {55, 59}, // G,/B,
152-          {60, 62}, // C/D
153-          {64, 65}, // E/F
154-          {67, 69}, // G/A
155-        },
156-        { // buttons
157-          {59, 57}, // B,/A,
158-          {62, 66}, // D/F^
159-          {67, 69}, // G/A
160-          {71, 72}, // B/c
161-          {74, 76}, // d/e
162-        },
163-        { // buttons
164-          {-1, -1}, // -
165-          {-1, -1}, // -
166-          {-1, -1}, // -
167-          {-1, -1}, // -
168-          {50, 50}, // D,/D,
169-        },
170-      },
171-      { // rows
172-        { // buttons
173-          {75, 73}, // d^/c^
174-          {73, 75}, // c^/d^
175-          {80, 79}, // g^/g
176-          {85, 82}, // c^'/b_
177-          {93, 86}, // a'/d'
178-        },
179-        { // buttons
180-          {72, 71}, // c/B
181-          {76, 74}, // e/d
182-          {79, 77}, // g/f
183-          {84, 81}, // c'/a
184-          {88, 83}, // e'/b
185-        },
186-        { // buttons
187-          {79, 78}, // g/f^
188-          {83, 81}, // b/a
189-          {86, 84}, // d'/c'
190-          {91, 88}, // g'/e'
191-          {89, 90}, // f'/f^'
192-        },
193-        { // buttons
194-          {-1, -1}, // -
195-          {-1, -1}, // -
196-          {-1, -1}, // -
197-          {-1, -1}, // -
198-          {-1, -1}, // -
199-        },
200-      },
201-    }
202-  },
203-  { "Lachenal C/G",
204-    { // sides
205-      { // rows
206-        { // buttons
207-          {52, 53}, // E,/F,
208-          {57, 58}, // A,/B_,
209-          {61, 63}, // C^/D^
210-          {69, 67}, // A/G
211-          {68, 70}, // G^/B_
212-        },
213-        { // buttons
214-          {48, 55}, // C,/G,
215-          {55, 59}, // G,/B,
216-          {60, 62}, // C/D
217-          {64, 65}, // E/F
218-          {67, 69}, // G/A
219-        },
220-        { // buttons
221-          {59, 57}, // B,/A,
222-          {62, 66}, // D/F^
223-          {67, 69}, // G/A
224-          {71, 72}, // B/c
225-          {74, 76}, // d/e
226-        },
227-        { // buttons
228-          {-1, -1}, // -
229-          {-1, -1}, // -
230-          {-1, -1}, // -
231-          {-1, -1}, // -
232-          {50, 50}, // D,/D,
233-        },
234-      },
235-      { // rows
236-        { // buttons
237-          {73, 75}, // c^/d^
238-          {81, 79}, // a/g
239-          {80, 82}, // g^/b_
240-          {85, 87}, // c^'/d^'
241-          {93, 89}, // a'/f'
242-        },
243-        { // buttons
244-          {72, 71}, // c/B
245-          {76, 74}, // e/d
246-          {79, 77}, // g/f
247-          {84, 81}, // c'/a
248-          {88, 83}, // e'/b
249-        },
250-        { // buttons
251-          {79, 78}, // g/f^
252-          {83, 81}, // b/a
253-          {86, 84}, // d'/c'
254-          {91, 88}, // g'/e'
255-          {95, 90}, // b'/f^'
256-        },
257-        { // buttons
258-          {-1, -1}, // -
259-          {-1, -1}, // -
260-          {-1, -1}, // -
261-          {-1, -1}, // -
262-          {-1, -1}, // -
263-        },
264-      },
265-    }
266-  },
267-};
A src/Makefile
+38, -0
 1@@ -0,0 +1,38 @@
 2+MCU = attiny85
 3+
 4+CC = avr-gcc
 5+CFLAGS += -mmcu=$(MCU)
 6+CFLAGS += -Os
 7+CFLAGS += -w
 8+
 9+## XXX does this really need to be duplicated?
10+LDFLAGS += -mmcu=$(MCU)
11+
12+all: $(TARGETS)
13+
14+blink.elf: blink.o
15+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
16+
17+%.hex: %.elf
18+	avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
19+
20+clean:
21+	rm -f *.elf *.o *.hex .upload
22+
23+
24+
25+##
26+## Helpful targets for development
27+##
28+
29+
30+AVDFLAGS += -p $(MCU)
31+AVDFLAGS += -c usbtiny
32+
33+upload: blink.hex
34+	avrdude $(AVDFLAGS) -U flash:w:$<
35+
36+fuses: FUSES += -U lfuse:w:0x62:m
37+fuses: FUSES += -U hfuse:w:0xDF:m
38+fuses:
39+	avrdude $(AVDFLAGS) $(FUSES)
A src/blink.c
+27, -0
 1@@ -0,0 +1,27 @@
 2+#include <stdbool.h>
 3+#include <stdint.h>
 4+#include <avr/io.h>
 5+#include <avr/interrupt.h>
 6+
 7+void init(void) {
 8+  DDRB = 0xff; // All port B pins are outputs
 9+}
10+
11+void loop(void) {
12+  static uint32_t count = 0;
13+
14+  if (count++ == 20000) {
15+    PORTB ^= 0x01; // Toggle pin 0
16+    count = 0;
17+  }
18+}
19+
20+int main(void) {
21+	init();
22+
23+	for (;;) {
24+		loop();
25+	}
26+
27+	return 0;
28+}
R concertina.ino => src/concertina.ino
+6, -2
 1@@ -22,8 +22,13 @@
 2 #define MIDI_CHAN_VOLUME 0x07
 3 #define MIDI_CHAN_PROGRAM 0xC0
 4 
 5-#define VS1053_MIDI Serial1 // Serial1 on the ItsyBitsy M0 Express is marked on the silkscreen
 6+// Serial1 on the ItsyBitsy M0 Express is marked on the silkscreen
 7+#define VS1053_MIDI Serial1
 8+
 9+// There's only one DotStar
10 Adafruit_DotStar DotStar(DOTSTAR_NUM, PIN_DOTSTAR_DATA, PIN_DOTSTAR_CLK, DOTSTAR_BRG);
11+
12+// An itsy bitsy OLED display
13 U8G2_SSD1306_64X32_1F_F_HW_I2C Display(U8G2_R0);
14 
15 /* Maps grid positions to layout positions.
16@@ -94,7 +99,6 @@ void setup() {
17   Display.firstPage();
18   Display.setFont(u8g2_font_helvR08_tf);
19   Display.drawUTF8(0, 10, currentLayout.name);
20-  Display.drawXBM(32, 0, 30, 32, ruby_xbm);
21   Display.nextPage();
22 
23   // Turn off the DotStar
R layouts.txt => src/layouts.txt
+0, -0
R mklayouts.py => src/mklayouts.py
+0, -0
R ruby.h => src/ruby.h
+0, -0