reform

MNT Reform: Open Source Portable Computer
Log (Feed) | Files | Refs (Tags) | README

commit 1b65e81cee9d545f44f138bdfdec0cfb4fb1ca02
parent 33bcef3c9180dfcb3ff9a0f13fff8ae616042e99
Author: minute <lukas@mntre.com>
Date:   Mon, 21 Feb 2022 17:53:50 +0000

Merge branch 'kbd-bitmaps' into 'master'

Enhanced keyboard firmware

See merge request reform/reform!25
Diffstat:
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Black.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Black.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-BlackItalic.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-BlackItalic.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Bold.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Bold.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-BoldItalic.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-BoldItalic.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Italic.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Italic.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Medium.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Medium.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-MediumItalic.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-MediumItalic.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Regular.woff | 0
Areform2-keyboard-editor/inter_ui_webfont/Inter-UI-Regular.woff2 | 0
Areform2-keyboard-editor/inter_ui_webfont/inter-ui.css | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-editor/mnt-reform-keyboard-firmware.js | 1+
Areform2-keyboard-editor/mnt-reform-keyboard.js | 451+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-editor/refkbd.html | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-editor/style.css | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dreform2-keyboard-fw/Descriptors.c | 219-------------------------------------------------------------------------------
Dreform2-keyboard-fw/Descriptors.h | 93-------------------------------------------------------------------------------
Dreform2-keyboard-fw/Keyboard.c | 1067-------------------------------------------------------------------------------
Dreform2-keyboard-fw/Keyboard.h | 91-------------------------------------------------------------------------------
Mreform2-keyboard-fw/Makefile | 4++--
Areform2-keyboard-fw/README.md | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/backlight.c | 41+++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/backlight.h | 15+++++++++++++++
Areform2-keyboard-fw/constants.h | 21+++++++++++++++++++++
Areform2-keyboard-fw/descriptors.c | 279+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/descriptors.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mreform2-keyboard-fw/flash.sh | 2+-
Mreform2-keyboard-fw/font.c | 6++++++
Areform2-keyboard-fw/hid_report.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/hid_report.h | 14++++++++++++++
Mreform2-keyboard-fw/i2c.c | 6++++++
Mreform2-keyboard-fw/i2c.h | 12++++++++++--
Areform2-keyboard-fw/kbdgfx-demo/build.sh | 4++++
Areform2-keyboard-fw/kbdgfx-demo/kbdgfx.c | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/kbdgfx-demo/picture-floyd.sh | 9+++++++++
Areform2-keyboard-fw/kbdgfx-demo/picture.sh | 7+++++++
Areform2-keyboard-fw/kbdgfx-demo/text.sh | 7+++++++
Areform2-keyboard-fw/keyboard.c | 445+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/keyboard.h | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/matrix.h | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/matrix_v.h | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/menu.c | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/menu.h | 22++++++++++++++++++++++
Areform2-keyboard-fw/oled.c | 356+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/oled.h | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/powersave.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/powersave.h | 12++++++++++++
Areform2-keyboard-fw/remote.c | 384+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/remote.h | 29+++++++++++++++++++++++++++++
Mreform2-keyboard-fw/scancodes.h | 15+++++++++++++++
Dreform2-keyboard-fw/ssd1306.c | 304-------------------------------------------------------------------------------
Dreform2-keyboard-fw/ssd1306.h | 96-------------------------------------------------------------------------------
58 files changed, 3485 insertions(+), 1875 deletions(-)

diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Black.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Black.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Black.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Black.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BlackItalic.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BlackItalic.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BlackItalic.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BlackItalic.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Bold.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Bold.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Bold.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Bold.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BoldItalic.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BoldItalic.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BoldItalic.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-BoldItalic.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Italic.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Italic.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Italic.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Italic.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Medium.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Medium.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Medium.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Medium.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-MediumItalic.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-MediumItalic.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-MediumItalic.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-MediumItalic.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Regular.woff b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Regular.woff Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Regular.woff2 b/reform2-keyboard-editor/inter_ui_webfont/Inter-UI-Regular.woff2 Binary files differ. diff --git a/reform2-keyboard-editor/inter_ui_webfont/inter-ui.css b/reform2-keyboard-editor/inter_ui_webfont/inter-ui.css @@ -0,0 +1,59 @@ +@font-face { + font-family: 'Inter UI'; + font-style: normal; + font-weight: 400; + src: url("Inter-UI-Regular.woff2") format("woff2"), + url("Inter-UI-Regular.woff") format("woff"); +} +@font-face { + font-family: 'Inter UI'; + font-style: italic; + font-weight: 400; + src: url("Inter-UI-Italic.woff2") format("woff2"), + url("Inter-UI-Italic.woff") format("woff"); +} + +@font-face { + font-family: 'Inter UI'; + font-style: normal; + font-weight: 500; + src: url("Inter-UI-Medium.woff2") format("woff2"), + url("Inter-UI-Medium.woff") format("woff"); +} +@font-face { + font-family: 'Inter UI'; + font-style: italic; + font-weight: 500; + src: url("Inter-UI-MediumItalic.woff2") format("woff2"), + url("Inter-UI-MediumItalic.woff") format("woff"); +} + +@font-face { + font-family: 'Inter UI'; + font-style: normal; + font-weight: 700; + src: url("Inter-UI-Bold.woff2") format("woff2"), + url("Inter-UI-Bold.woff") format("woff"); +} +@font-face { + font-family: 'Inter UI'; + font-style: italic; + font-weight: 700; + src: url("Inter-UI-BoldItalic.woff2") format("woff2"), + url("Inter-UI-BoldItalic.woff") format("woff"); +} + +@font-face { + font-family: 'Inter UI'; + font-style: normal; + font-weight: 900; + src: url("Inter-UI-Black.woff2") format("woff2"), + url("Inter-UI-Black.woff") format("woff"); +} +@font-face { + font-family: 'Inter UI'; + font-style: italic; + font-weight: 900; + src: url("Inter-UI-BlackItalic.woff2") format("woff2"), + url("Inter-UI-BlackItalic.woff") format("woff"); +} diff --git a/reform2-keyboard-editor/mnt-reform-keyboard-firmware.js b/reform2-keyboard-editor/mnt-reform-keyboard-firmware.js @@ -0,0 +1 @@ +var defaultFirmware = "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AQMQCQwAAQN2CQIAAQN/CQYAAQN/CQgAAQMGCQIAAQMDCQQAAQMrCQQAAQN+CQQAAQMGCQIAAQkGAAABASgUAAACABMCAAACAfsOCgABAQEBAAAAAS4vbHVmYS1tYXN0ZXIvTFVGQS9Ecml2ZXJzL1VTQi9Db3JlL0FWUjgALi9sdWZhLW1hc3Rlci9MVUZBL0RyaXZlcnMvVVNCL0NvcmUvQVZSOC8uLi9BVlI4Ly4uL0FWUjgALi9sdWZhLW1hc3Rlci9MVUZBL0RyaXZlcnMvVVNCL0NvcmUvQVZSOC9UZW1wbGF0ZQAvdXNyL2xpYi9hdnIvaW5jbHVkZQAuL2x1ZmEtbWFzdGVyL0xVRkEvRHJpdmVycy9VU0IvQ29yZS9BVlI4Ly4uL0FWUjgvLi4ALi9sdWZhLW1hc3Rlci9MVUZBL0RyaXZlcnMvVVNCL0NvcmUvQVZSOC8uLgAvdXNyL2xpYi9hdnIvaW5jbHVkZS9hdnIAAEVuZHBvaW50U3RyZWFtX0FWUjguYwABAABFbmRwb2ludF9BVlI4LmgAAgAAVGVtcGxhdGVfRW5kcG9pbnRfUlcuYwADAABUZW1wbGF0ZV9FbmRwb2ludF9Db250cm9sX1cuYwADAABUZW1wbGF0ZV9FbmRwb2ludF9Db250cm9sX1IuYwADAABzdGRpbnQuaAAEAABTdGRSZXF1ZXN0VHlwZS5oAAUAAERldmljZS5oAAUAAEVuZHBvaW50U3RyZWFtLmgABQAAVVNCVGFzay5oAAYAAGVlcHJvbS5oAAcAAAAABQIAAAAAAysBAwQJAAABAwMJAAABAwEJAAABA3gJAAABAwoJAAABBAIDsgIJAAABBAED0H0JAAABBAIDnwMJAAABBAED5XwJAAABAwIJAAABAwEJAAABAwMJAAABBAID9AMJAAABBAEDk3wJAAABAwEJAAABAwQJAAABAwEJAAABCQAAAAEBAAUCAAAAAAPSAAEDBAkAAAEDAwkAAAEDAQkAAAEDeAkAAAEDCgkAAAEEAgOLAgkAAAEEAQP3fQkAAAEEAgPpAgkAAAEEAQObfQkAAAEDAgkAAAEDAQkAAAEDAwkAAAEEAgPBAwkAAAEEAQPGfAkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAlAeAAADIwEDBQkWAAEDAwkGAAEDAgkGAAEDAQkKAAEDdgkEAAEDDQkEAAEEAgO2AgkGAAEEAwPMfQkEAAEEAgOUAwkEAAEEAwPxfAkIAAEDAwkEAAEDAgkGAAEDAQkOAAEDAwkCAAEDBQkKAAEEAgPjAwkCAAEEAwOffAkEAAEDAQkEAAEDBAkIAAEDAQkCAAEJEgAAAQEEAwAFAgAAAAADIwEDBQkAAAEDfAkAAAEDBwkAAAEDAgkAAAEDAQkAAAEDdQkAAAEDDgkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOUAwkAAAEEAwPxfAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEDBQkAAAEEAgPjAwkAAAEEAwOefAkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDdgkAAAEDDQkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOjAwkAAAEEAwPifAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEEAgPcAwkAAAEEAwOpfAkAAAEDAgkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDfAkAAAEDBwkAAAEDAgkAAAEDAQkAAAEDdQkAAAEDDgkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOjAwkAAAEEAwPifAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEEAgPcAwkAAAEEAwOpfAkAAAEDAQkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDdgkAAAEDDQkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOUAwkAAAEEAwPxfAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEDBQkAAAEEAgPjAwkAAAEEAwOefAkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDfAkAAAEDBwkAAAEDAgkAAAEDAQkAAAEDdQkAAAEDDgkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOUAwkAAAEEAwPxfAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEDBQkAAAEEAgPjAwkAAAEEAwOefAkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDdgkAAAEDDQkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOUAwkAAAEEAwPxfAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEDBQkAAAEEAgPjAwkAAAEEAwOefAkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDfAkAAAEDBwkAAAEDAgkAAAEDAQkAAAEDdQkAAAEDDgkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOUAwkAAAEEAwPxfAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEDBQkAAAEEAgPjAwkAAAEEAwOefAkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDdgkAAAEDDQkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOjAwkAAAEEAwPifAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEEAgPcAwkAAAEEAwOpfAkAAAEDAQkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEAwAFAgAAAAADIwEDBQkAAAEDfAkAAAEDBwkAAAEDAgkAAAEDAQkAAAEDdQkAAAEDDgkAAAEEAgO2AgkAAAEEAwPMfQkAAAEEAgOjAwkAAAEEAwPifAkAAAEDAwkAAAEDAgkAAAEDAQkAAAEDAwkAAAEEAgPcAwkAAAEEAwOpfAkAAAEDAQkAAAEDAQkAAAEDAQkAAAEDBAkAAAEDAQkAAAEJAAAAAQEEBAAFAuQeAAADIgEDBAkAAAEDAgkOAAEEAgOfAwkGAAEEBAPkfAkSAAEDAgkGAAEDAgkEAAEDAgkEAAEEAgP9AgkEAAEEBAOFfQkEAAEEAgPvAgkEAAEEBAOTfQkEAAEEAgPhAgkEAAEEBAOifQkEAAEEAgOqAQkEAAEEBAPafgkMAAEAAgQBBgMACQYAAQYDAgkGAAEEAgPrAwkCAAEEBAOXfAkEAAEDAQkEAAEDAwkEAAEEAgODAwkI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UkUAUElORQBQT1JURgBERFJGAFBJTkYAVFdBTVIAVFdCUgBUV0NSAFRXU1IAVFdEUgBUV0FSAEFETVVYAEFEQ1NSQQBBREMAQURDU1JCAERJRFIwAERJRFIyAEFEQ1NSQgBBQ1NSAERJRFIxAFNSRUcAU1AATUNVQ1IATUNVU1IAT1NDQ0FMAFJDQ1RSTABDTEtQUgBTTUNSAEVJTkQAR1BJT1IyAEdQSU9SMQBHUElPUjAAUFJSMQBQUlIwAENMS1NUQQBDTEtTRUwxAENMS1NFTDAAUExMQ1NSAFBMTEZSUQBVRUlOVABVRUJDSFgAVUVCQ0xYAFVFREFUWABVRUlFTlgAVUVTVEExWABVRVNUQTBYAFVFQ0ZHMVgAVUVDRkcwWABVRUNPTlgAVUVSU1QAVUVOVU0AVUVJTlRYAFVETUZOAFVERk5VTQBVREFERFIAVURJRU4AVURJTlQAVURDT04AVVNCQ09OAFVTQklOVABVU0JTVEEAVUhXQ09OAGV4ZWN1dGVfbWV0YV9mdW5jdGlvbgBVU0JfRW5kcG9pbnRfVGFibGVfdABLZXlib2FyZF9ISURfSW50ZXJmYWNlAGN1cnJlbnRfc2Nyb2xsX3kAZ2Z4X2NvbnRyYXN0AHNwcmludGYAY2xvY2tfZGl2XzE2AF9kZWxheV9tcwBjbG9ja19kaXZfMQBVU0JfS2V5Ym9hcmRSZXBvcnRfRGF0YV90AG9sZWRfYnJpZ2h0bmVzc19pbmMAY2xvY2tfZGl2XzQAY2xvY2tfZGl2XzgASElEX0RldmljZV9VU0JUYXNrAGdhdWdlX29mZnNldABkb25lAFJlc2VydmVkAHJlbW90ZV9nZXRfc3RhdHVzAHRlcm1feAB0ZXJtX3kAUHJldlJlcG9ydElOQnVmZmVyU2l6ZQBQcmV2S2V5Ym9hcmRISURSZXBvcnRCdWZmZXIAbG9uZyBsb25nIHVuc2lnbmVkIGludABhbXBzX29mZnNldABFVkVOVF9VU0JfRGV2aWNlX0NvbnRyb2xSZXF1ZXN0AElOVEVSRkFDRV9JRF9LZXlib2FyZABDb25maWdTdWNjZXNzAGJhdF9hbXBzAHByaW50AHJlbW90ZV90dXJuX29mZl9zb20Aa2JkX2JyaWdodG5lc3NfaW5pdABtYXRyaXgAa2V5Y29kZQBJZGxlTVNSZW1haW5pbmcASElEX0RldmljZV9NaWxsaXNlY29uZEVsYXBzZWQAbG9uZyBsb25nIGludABleGVjdXRlX21lbnVfZnVuY3Rpb24AQmF1ZFJhdGUAdG90YWxfcHJlc3NlZAByZW1vdGVfdHVybl9vZmZfYXV4AGNsb2NrX2Rpdl90AFJlcG9ydERhdGEAdXNiX3JlcG9ydF9tb2RlAFNlcmlhbF9Jbml0AFVTQl9EZXZpY2VfRW5hYmxlU09GRXZlbnRzAGJhdF92b2x0cwBjbG9ja19kaXZfMTI4AC9ob21lL21udG1uL2NvZGUvcmVmb3JtL3JlZm9ybTIta2V5Ym9hcmQtZncAbWF0cml4X3N0YXRlAHJlbW90ZV9yZWNlaXZlX3N0cmluZwByZXNfeABkb3VibGUAaW5zZXJ0X2JhdF9pY29uAEVWRU5UX1VTQl9EZXZpY2VfU3RhcnRPZkZyYW1lAGdmeF9wb2tlX3N0cgBISURfRGV2aWNlX0NvbmZpZ3VyZUVuZHBvaW50cwBJbnRlcmZhY2VOdW1iZXIAZ2Z4X29mZgBnZnhfaW5pdABsYXN0X21ldGFfa2V5AGdmeF9mbHVzaABfX3RtcABJZGxlQ291bnQAUmVwb3J0SUQAUHJldlJlcG9ydElOQnVmZmVyAHdkdF9kaXNhYmxlAE1lbnVJdGVtAHN0cm5jcHkAdWludDE2X3QAdXNlZF9rZXlfY29kZXMAR05VIEM5OSA1LjQuMCAtbW4tZmxhc2g9MSAtbW5vLXNraXAtYnVnIC1tcmVsYXggLW1tY3U9YXZyNSAtZ2R3YXJmLTIgLWcyIC1PcyAtc3RkPWdudTk5IC1mc2hvcnQtZW51bXMgLWZuby1pbmxpbmUtc21hbGwtZnVuY3Rpb25zIC1mbm8tc3RyaWN0LWFsaWFzaW5nIC1mdW5zaWduZWQtY2hhciAtZnVuc2lnbmVkLWJpdGZpZWxkcyAtZmZ1bmN0aW9uLXNlY3Rpb25zIC1mbm8tanVtcC10YWJsZXMAY2xvY2tfZGl2XzIAVVNCX0lOVF9TVVNQSQB0aW1lb3V0AE1vZGlmaWVyAGxvd19iYXR0ZXJ5X2FsZXJ0AFVTQl9JTlRfVkJVU1RJAFNlcmlhbF9Jc1NlbmRSZWFkeQBkYXRhAGNsb2NrX2Rpdl8zMgB0ZW1wX3JlZwBVU0JfQ2xhc3NJbmZvX0hJRF9EZXZpY2VfdABQcmV2RnJhbWVOdW0ASElEX0RldmljZV9Qcm9jZXNzQ29udHJvbFJlcXVlc3QAY2xvY2tfZGl2XzI1NgBwb2tlX2NocgBrYmRfYnJpZ2h0bmVzc19kZWMAYW5pbV9nb29kYnllAF9fbXMAcmVuZGVyX21lbnUAVVNCX1VTQlRhc2sAbWVudV9pdGVtcwBFVkVOVF9VU0JfRGV2aWNlX0Rpc2Nvbm5lY3QAcHJvY2Vzc19hbGVydHMAX191cwByZW1vdGVfY2hlY2tfZm9yX2xvd19iYXR0ZXJ5AEludGVycnVwdABfZGVsYXlfdXMAb2xlZGJydABzaXpldHlwZQBkZWJvdW5jZWRfcHJlc3NlZABVU0JfRGV2aWNlU3RhdGUAQ0FMTEJBQ0tfSElEX0RldmljZV9Qcm9jZXNzSElEUmVwb3J0AGtiZF9icmlnaHRuZXNzX3NldABVU0JfSW5pdAB0aXRsZQByZW1vdGVfd2FrZV9zb20AZ2Z4X2NsZWFyX2ludmVydABnZnhfcG9rZQBVU0JfSU5UX1NPRkkAY3Vyc29yAEludGVyZmFjZURlc2NyaXB0b3JzX3QAcl9pbmJ1ZgBLZXlDb2RlAGZsb2F0AEtleWJvYXJkLmMAa2JkX2JyaWdodG5lc3NfaW5jAFNldHVwSGFyZHdhcmUAZGlydHkAYXRvaQBfX2J1aWx0aW5fYXZyX2RlbGF5X2N5Y2xlcwBfQm9vbAB1bnNpZ25lZCBjaGFyAGFjdGl2ZV9tZXRhX21vZGUAY2xvY2tfcHJlc2NhbGVfc2V0AEJhbmtzAFVTQl9JTlRfV0FLRVVQSQBjb3VudGVyAHJlc3BvbnNlAHN1bV92b2x0cwByZW1vdGVfdHVybl9vbl9zb20Adm9sdHNfb2Zmc2V0AEtleWJvYXJkUmVwb3J0AFNlcmlhbF9Jc0NoYXJSZWNlaXZlZAB1aW50MzJfdABNaWxsaXNlY29uZHMAYW5pbV9oZWxsbwBVU0JfSU5UX1JYU1RQSQByZW1vdGVfZGlzYWJsZV9zb21fdWFydAByZW1vdGVfdHVybl9vbl9hdXgARG91YmxlU3BlZWQAcGVyY2VudABvbGVkX2JyaWdodG5lc3NfZGVjAHB3bXZhbAByZW1vdGVfZ2V0X3ZvbHRhZ2VzAFNlcmlhbF9TZW5kQnl0ZQBjbG9ja19kaXZfNjQAcHJvY2Vzc19rZXlib2FyZABzdGF5X21ldGEAZW1wdHlfc2VyaWFsAFVzaW5nUmVwb3J0UHJvdG9jb2wAVVNCX0lOVF9FT1JTVEkAbWF0cml4X2RlYm91bmNlAENBTExCQUNLX0hJRF9EZXZpY2VfQ3JlYXRlSElEUmVwb3J0AF9fdGlja3NfZGMAcmVtb3RlX3JlcG9ydF92b2x0YWdlcwBDb25maWcASElESW50ZXJmYWNlSW5mbwBibGluawBHbG9iYWxJbnRlcnJ1cHRFbmFibGUAZ2Z4X29uAFJlcG9ydFNpemUAcmVtb3RlX2VuYWJsZV9zb21fdWFydAB1aW50OF90AFVTQl9JTlRfRW5hYmxlAGN1cnJlbnRfbWVudV95AFNlcmlhbF9SZWNlaXZlQnl0ZQBFVkVOVF9VU0JfRGV2aWNlX0NvbmZpZ3VyYXRpb25DaGFuZ2VkAHJlbW90ZV9yZXNldF9zb20ARGVsYXlfTVMAZ2Z4X2NsZWFyAGJhdF9nYXVnZQBDaGFyYWN0ZXJNYXRyaXgAY2xvY2sARGF0YUJ5dGUAZ2Z4X2ludmVydF9yb3cAbWFpbgBicml0ZQBVU0JfSW50ZXJydXB0c190AENvbmZpZ3VyYXRpb25TdHJJbmRleABEVFlQRV9PdGhlcgBUb3RhbENvbmZpZ3VyYXRpb25TaXplAFVTQl9EZXNjcmlwdG9yX0VuZHBvaW50X3QARFRZUEVfRW5kcG9pbnQASElEX0NTQ1BfS2V5Ym9hcmRCb290UHJvdG9jb2wAU3RyaW5nRGVzY3JpcHRvcnNfdABOdW1iZXJPZkNvbmZpZ3VyYXRpb25zAEVuZHBvaW50U2l6ZQBISURfQ1NDUF9Ob25Cb290UHJvdG9jb2wATWFudWZhY3R1cmVyU3RySW5kZXgASElEX0tleWJvYXJkSElEAFVTQl9DU0NQX1ZlbmRvclNwZWNpZmljUHJvdG9jb2wARFRZUEVfU3RyaW5nAFZlbmRvcklEAEVuZHBvaW50QWRkcmVzcwBJbnRlcmZhY2VTdHJJbmRleABVU0JfQ1NDUF9Ob0RldmljZUNsYXNzAEhJRF9EVFlQRV9ISUQAUHJvZHVjdFN0cmluZwBVU0JfRGVzY3JpcHRvcl9IZWFkZXJfdABEZXNjcmlwdG9yVHlwZQBfX2FkZHIxNgBISURfQ1NDUF9Cb290U3ViY2xhc3MASElEX0Rlc2NyaXB0b3JfQ2xhc3NTdWJjbGFzc1Byb3RvY29sX3QASElEU3BlYwBBbHRlcm5hdGVTZXR0aW5nAFByb2R1Y3RTdHJJbmRleABEZXNjcmlwdG9ycy5jAFRvdGFsUmVwb3J0RGVzY3JpcHRvcnMAQ29uZmlndXJhdGlvbkRlc2NyaXB0b3IAVVNCX0NTQ1BfSUFERGV2aWNlUHJvdG9jb2wASElEX1JlcG9ydElORW5kcG9pbnQAU1RSSU5HX0lEX1Byb2R1Y3QAVVNCX0NTQ1BfSUFERGV2aWNlQ2xhc3MAd1ZhbHVlAFVTQl9ISURfRGVzY3JpcHRvcl9ISURfdABISURfQ1NDUF9Ob25Cb290U3ViY2xhc3MAU1RSSU5HX0lEX0xhbmd1YWdlAFVTQl9DU0NQX1ZlbmRvclNwZWNpZmljU3ViY2xhc3MASElEX0NTQ1BfSElEQ2xhc3MAU1RSSU5HX0lEX01hbnVmYWN0dXJlcgBISURfRGVzY3JpcHRvclR5cGVzX3QAVVNCX0NTQ1BfSUFERGV2aWNlU3ViY2xhc3MAVVNCX0Rlc2NyaXB0b3JfQ29uZmlndXJhdGlvbl90AFRvdGFsSW50ZXJmYWNlcwBEVFlQRV9DU0VuZHBvaW50AFRvdGFsRW5kcG9pbnRzAF9fcmVzdWx0AENBTExCQUNLX1VTQl9HZXREZXNjcmlwdG9yAERUWVBFX0RldmljZVF1YWxpZmllcgBEVFlQRV9JbnRlcmZhY2UATWFudWZhY3R1cmVyU3RyaW5nAERUWVBFX0RldmljZQBVbmljb2RlU3RyaW5nAHdjaGFyX3QAVVNCX0NTQ1BfTm9EZXZpY2VTdWJjbGFzcwBVU0JfRGVzY3JpcHRvcl9Db25maWd1cmF0aW9uX0hlYWRlcl90AEhJRFJlcG9ydExlbmd0aABVU0JfRGVzY3JpcHRvcl9JbnRlcmZhY2VfdABMYW5ndWFnZVN0cmluZwBISURfRFRZUEVfUmVwb3J0AERlc2NyaXB0b3JBZGRyZXNzAFByb2R1Y3RJRABDb25maWdBdHRyaWJ1dGVzAFJlbGVhc2VOdW1iZXIAU2VyaWFsTnVtU3RySW5kZXgASElEUmVwb3J0VHlwZQBFbmRwb2ludDBTaXplAFVTQl9DU0NQX05vRGV2aWNlUHJvdG9jb2wATWF4UG93ZXJDb25zdW1wdGlvbgBVU0JfRGVzY3JpcHRvcl9ISURSZXBvcnRfRGF0YXR5cGVfdABDb3VudHJ5Q29kZQBEZXZpY2VEZXNjcmlwdG9yAEhJRF9DU0NQX01vdXNlQm9vdFByb3RvY29sAERlc2NyaXB0b3JOdW1iZXIARFRZUEVfQ29uZmlndXJhdGlvbgBVU0JfQ1NDUF9WZW5kb3JTcGVjaWZpY0NsYXNzAFBvbGxpbmdJbnRlcnZhbE1TAERUWVBFX0ludGVyZmFjZVBvd2VyAFVTQlNwZWNpZmljYXRpb24ARFRZUEVfSW50ZXJmYWNlQXNzb2NpYXRpb24AU3ViQ2xhc3MAVVNCX0Rlc2NyaXB0b3JfU3RyaW5nX3QAVVNCX0Rlc2NyaXB0b3JfQ2xhc3NTdWJjbGFzc1Byb3RvY29sX3QARFRZUEVfQ1NJbnRlcmZhY2UAVVNCX0Rlc2NyaXB0b3JUeXBlc190AHdJbmRleABVU0JfRGVzY3JpcHRvcl9EZXZpY2VfdABpMmNfbWFzdGVyX3N0YXJ0AGkyY19kZWxheQBpMmNfc2xhdmVfYnVmZmVyAGkyY19tYXN0ZXJfaW5pdABpMmNfbWFzdGVyX3dyaXRlAF9fdmVjdG9yXzM2AGkyY19tYXN0ZXJfc3RvcABpMmNfc2xhdmVfaW5pdABpMmMuYwBzbGF2ZV9idWZmZXJfcG9zAGFkZHJlc3MAc2xhdmVfaGFzX3JlZ2lzdGVyX3NldABpMmNfbWFzdGVyX3JlYWQAaTJjX3Jlc2V0X3N0YXRlAFNldENvbnRyYXN0AEV4dGVybmFsVmNjAE5vcm1hbERpc3BsYXkAVmVydGljYWxBbmRSaWdodEhvcml6b250YWxTY3JvbGwAZm9udABfc2VuZF9jbWQyAG9wcjEAb3ByMgBtYXRyaXhfd3JpdGVfY2hhcl9pbm5lcgBtYXRyaXhfd3JpdGVfUABTZXRNZW1vcnlNb2RlAGdseXBoQ29sAFNldFN0YXJ0TGluZQByb3RhdGUAc25wcmludGYAZ2Z4X3dyaXRlX1AAY29sQml0cwBnZnhfd3JpdGVfY2hhcgBtYXRyaXhfY2xlYXIAc3NkMTMwNl9jbWRzAFNldENvbVBpbnMARGlzcGxheU9uAGdmeF93cml0ZQBtYXRyaXhfd3JpdGUARGVBY3RpdmF0ZVNjcm9sbABEaXNwbGF5QWxsT24ASW52ZXJ0RGlzcGxheQBTZWdSZW1hcABnbHlwaABtZW1tb3ZlAFNldEhpZ2hDb2x1bW4AbWF0cml4X3dyaXRlX2NoYXIARGlzcGxheUFsbE9uUmVzdW1lAG1hdHJpeF9yZW5kZXIAYWRkcgBTZXRQcmVDaGFyZ2UAU2V0RGlzcGxheU9mZnNldABkYXRhX2xuAGN1cnNvcl9jb2wAY2xlYXJfZGlzcGxheQBEaXNwbGF5T2ZmAFNldE11bHRpUGxleABTZXRWZXJ0aWNhbFNjcm9sbEFyZWEAQ29tU2NhbkluYwBDb2x1bW5BZGRyAGdmeF9jbGVhcl9zY3JlZW4AU2V0Q2hhcmdlUHVtcABtZW1zZXQAaTJjX3N0YXJ0X3dyaXRlAFNldExvd0NvbHVtbgBTd2l0Y2hDYXBWY2MAU2V0RGlzcGxheUNsb2NrRGl2AHN1Y2Nlc3MAbWF0cml4X3dyaXRlX2xuAFBhZ2VBZGRyAHNzZDEzMDYuYwBDb21TY2FuRGVjAF9zZW5kX2NtZDEAX3NlbmRfY21kMwBWZXJ0aWNhbEFuZExlZnRIb3Jpem9udGFsU2Nyb2xsAFNldFZDb21EZXRlY3QARW5kcG9pbnRfQ2xlYXJJTgBFbmRwb2ludF9Xcml0ZV9Db250cm9sX1N0cmVhbV9CRQBlZXByb21fdXBkYXRlX2J5dGUAQnl0ZXNJblRyYW5zZmVyAC4vbHVmYS1tYXN0ZXIvTFVGQS9Ecml2ZXJzL1VTQi9Db3JlL0FWUjgvRW5kcG9pbnRTdHJlYW1fQVZSOC5jAEVORFBPSU5UX1JXU1RSRUFNX1RpbWVvdXQARW5kcG9pbnRfTnVsbF9TdHJlYW0ARU5EUE9JTlRfUldTVFJFQU1fTm9FcnJvcgBERVZJQ0VfU1RBVEVfVW5hdHRhY2hlZABCeXRlc1Byb2Nlc3NlZABERVZJQ0VfU1RBVEVfRGVmYXVsdABFTkRQT0lOVF9SV0NTVFJFQU1fRGV2aWNlRGlzY29ubmVjdGVkAEVuZHBvaW50X0lzU0VUVVBSZWNlaXZlZABFbmRwb2ludF9TdHJlYW1fUldfRXJyb3JDb2Rlc190AEVuZHBvaW50X0lzSU5SZWFkeQBEdW1teQBFbmRwb2ludF9SZWFkX0NvbnRyb2xfRVN0cmVhbV9CRQBVU0JfUmVxdWVzdF9IZWFkZXJfdABFbmRwb2ludF9Xcml0ZV9Db250cm9sX0VTdHJlYW1fQkUARW5kcG9pbnRfUmVhZF9TdHJlYW1fTEUAVVNCX0RldmljZV9TdGF0ZXNfdABFbmRwb2ludF9DbGVhck9VVABFbmRwb2ludF9Jc09VVFJlY2VpdmVkAEVuZHBvaW50X1JlYWRfQ29udHJvbF9TdHJlYW1fQkUARW5kcG9pbnRfV3JpdGVfQ29udHJvbF9QU3RyZWFtX0xFAGJtUmVxdWVzdFR5cGUARW5kcG9pbnRfV3JpdGVfRVN0cmVhbV9CRQBFbmRwb2ludF9Db250cm9sU3RyZWFtX1JXX0Vycm9yQ29kZXNfdABFbmRwb2ludF9Jc1JlYWRXcml0ZUFsbG93ZWQARW5kcG9pbnRfV3JpdGVfQ29udHJvbF9TdHJlYW1fTEUARW5kcG9pbnRfV2FpdFVudGlsUmVhZHkARGF0YVN0cmVhbQBFbmRwb2ludF9Xcml0ZV9QU3RyZWFtX0xFAEVORFBPSU5UX1JXU1RSRUFNX0luY29tcGxldGVUcmFuc2ZlcgBFbmRwb2ludF9Xcml0ZV9TdHJlYW1fQkUAREVWSUNFX1NUQVRFX0NvbmZpZ3VyZWQARXJyb3JDb2RlAEVuZHBvaW50X1dyaXRlX1N0cmVhbV9MRQBVU0JfRGV2aWNlU3RhdGVfTENMAERFVklDRV9TVEFURV9TdXNwZW5kZWQAVVNCX0NvbnRyb2xSZXF1ZXN0AEVORFBPSU5UX1JXU1RSRUFNX0VuZHBvaW50U3RhbGxlZABFbmRwb2ludF9SZWFkX0NvbnRyb2xfRVN0cmVhbV9MRQBFbmRwb2ludF9Xcml0ZV9Db250cm9sX0VTdHJlYW1fTEUAZWVwcm9tX3JlYWRfYnl0ZQBERVZJQ0VfU1RBVEVfQWRkcmVzc2VkAERFVklDRV9TVEFURV9Qb3dlcmVkAEVuZHBvaW50X1dyaXRlXzgARW5kcG9pbnRfUmVhZF9FU3RyZWFtX0JFAEVuZHBvaW50X1JlYWRfQ29udHJvbF9TdHJlYW1fTEUARW5kcG9pbnRfUmVhZF9TdHJlYW1fQkUARW5kcG9pbnRfV3JpdGVfRVN0cmVhbV9MRQBFbmRwb2ludF9Xcml0ZV9QU3RyZWFtX0JFAGJSZXF1ZXN0AEVuZHBvaW50X0Rpc2NhcmRfOABFTkRQT0lOVF9SV1NUUkVBTV9EZXZpY2VEaXNjb25uZWN0ZWQARW5kcG9pbnRfRGlzY2FyZF9TdHJlYW0ARW5kcG9pbnRfQnl0ZXNJbkVuZHBvaW50AEVuZHBvaW50X1JlYWRfOABFTkRQT0lOVF9SV0NTVFJFQU1fQnVzU3VzcGVuZGVkAEVORFBPSU5UX1JXQ1NUUkVBTV9Ob0Vycm9yAExhc3RQYWNrZXRGdWxsAEVORFBPSU5UX1JXU1RSRUFNX0J1c1N1c3BlbmRlZABFbmRwb2ludF9SZWFkX0VTdHJlYW1fTEUARU5EUE9JTlRfUldDU1RSRUFNX0hvc3RBYm9ydGVkAHdMZW5ndGgARW5kcG9pbnRfV3JpdGVfQ29udHJvbF9QU3RyZWFtX0JFAEVuZHBvaW50X1NlbGVjdEVuZHBvaW50AFVFQ0ZHMFhEYXRhAFVFQ0ZHMVhUZW1wAEVuZHBvaW50X0J5dGVzVG9FUFNpemVNYXNrAENoZWNrQnl0ZXMARW5kcG9pbnRfSXNTdGFsbGVkAFByZXZpb3VzRnJhbWVOdW1iZXIARW5kcG9pbnRfV2FpdFVudGlsUmVhZHlfRXJyb3JDb2Rlc190AEVuZHBvaW50X0NvbmZpZ3VyZUVuZHBvaW50AEVuZHBvaW50X0Rpc2FibGVFbmRwb2ludABVRUlFTlhUZW1wAFRpbWVvdXRNU1JlbQBFUE51bQBVRUNGRzFYRGF0YQBFbnRyaWVzAEVORFBPSU5UX1JFQURZV0FJVF9UaW1lb3V0AEVORFBPSU5UX1JFQURZV0FJVF9FbmRwb2ludFN0YWxsZWQARW5kcG9pbnRfRW5hYmxlRW5kcG9pbnQALi9sdWZhLW1hc3Rlci9MVUZBL0RyaXZlcnMvVVNCL0NvcmUvQVZSOC9FbmRwb2ludF9BVlI4LmMAVUVDRkcwWFRlbXAARW5kcG9pbnRfQ2xlYXJFbmRwb2ludHMARW5kcG9pbnRfQ29uZmlndXJlRW5kcG9pbnRUYWJsZQBFbmRwb2ludF9DbGVhclN0YXR1c1N0YWdlAE1hc2tWYWwAQ3VycmVudEZyYW1lTnVtYmVyAEVORFBPSU5UX1JFQURZV0FJVF9EZXZpY2VEaXNjb25uZWN0ZWQARW5kcG9pbnRfR2V0RW5kcG9pbnREaXJlY3Rpb24ARU5EUE9JTlRfUkVBRFlXQUlUX05vRXJyb3IARW5kcG9pbnRfSXNDb25maWd1cmVkAFVTQl9EZXZpY2VfR2V0RnJhbWVOdW1iZXIARU5EUE9JTlRfUkVBRFlXQUlUX0J1c1N1c3BlbmRlZABFbmRwb2ludF9Db25maWd1cmVFbmRwb2ludF9QcnYAVVNCX01PREVfRGV2aWNlAFVTQl9NT0RFX1VJRABVU0JfT1RHUEFEX09mZgBVU0JfQXR0YWNoAFVTQl9NT0RFX05vbmUAVVNCX1JFR19PZmYAVVNCX0lOVF9DbGVhckFsbEludGVycnVwdHMAVVNCX0luaXRfRGV2aWNlAFVTQl9SRUdfT24AVVNCX0RldGFjaABVU0JfT1RHUEFEX09uAFVTQl9Db250cm9sbGVyX0Rpc2FibGUAVVNCX0RldmljZV9Db25maWd1cmF0aW9uTnVtYmVyAFVTQl9EZXZpY2VfQ3VycmVudGx5U2VsZlBvd2VyZWQAVVNCX1Jlc2V0SW50ZXJmYWNlAFVTQl9Db250cm9sbGVyX1Jlc2V0AFVTQl9EZXZpY2VfU2V0RnVsbFNwZWVkAFVTQl9NT0RFX0hvc3QAVVNCX1BMTF9PZmYAVVNCX0Rpc2FibGUAVVNCX01vZGVzX3QAVVNCX0lOVF9DbGVhcgBVU0JfQ0xLX1VuZnJlZXplAFVTQl9Jc0luaXRpYWxpemVkAC4vbHVmYS1tYXN0ZXIvTFVGQS9Ecml2ZXJzL1VTQi9Db3JlL0FWUjgvVVNCQ29udHJvbGxlcl9BVlI4LmMAVVNCX0RldmljZV9SZW1vdGVXYWtldXBFbmFibGVkAFVTQl9JTlRfRGlzYWJsZUFsbEludGVycnVwdHMAVVNCX1ZCVVNfR2V0U3RhdHVzAFVTQl9DTEtfRnJlZXplAFVTQl9QTExfSXNSZWFkeQBVU0JfSU5UX0hhc09jY3VycmVkAFVTQl9QTExfT24AVVNCX0lOVF9Jc0VuYWJsZWQARVZFTlRfVVNCX0RldmljZV9XYWtlVXAARVZFTlRfVVNCX0RldmljZV9SZXNldABVU0JfSU5UX0Rpc2FibGUAVVNCX0RldmljZV9Jc0FkZHJlc3NTZXQARVZFTlRfVVNCX0RldmljZV9Db25uZWN0AC4vbHVmYS1tYXN0ZXIvTFVGQS9Ecml2ZXJzL1VTQi9Db3JlL0FWUjgvVVNCSW50ZXJydXB0X0FWUjguYwBFVkVOVF9VU0JfRGV2aWNlX1N1c3BlbmQAX192ZWN0b3JfMTAAUkVRX1NldENvbmZpZ3VyYXRpb24AU2V0R2xvYmFsSW50ZXJydXB0TWFzawBFbmRwb2ludEluZGV4AFJFUV9TZXRGZWF0dXJlAFJFUV9HZXRTdGF0dXMAUmVxdWVzdEhlYWRlcgBGRUFUVVJFX1NFTF9EZXZpY2VSZW1vdGVXYWtldXAAQ3VycmVudEdsb2JhbEludABFbmRwb2ludF9TdGFsbFRyYW5zYWN0aW9uAFJFUV9TZXRJbnRlcmZhY2UARW5kcG9pbnRfQ2xlYXJTRVRVUABSRVFfU2V0QWRkcmVzcwBVU0JfRGV2aWNlX0dldEludGVybmFsU2VyaWFsRGVzY3JpcHRvcgBEZXNjcmlwdG9yUG9pbnRlcgBHZXRHbG9iYWxJbnRlcnJ1cHRNYXNrAFJFUV9HZXREZXNjcmlwdG9yAHVpbnRfcmVnX3QAVVNCX0NvbnRyb2xfUmVxdWVzdF90AFNlcmlhbENoYXJOdW0ARW5kcG9pbnRfUmVzZXRFbmRwb2ludABTaWduYXR1cmVEZXNjcmlwdG9yAFJFUV9HZXRJbnRlcmZhY2UAVVNCX0RldmljZV9DbGVhclNldEZlYXR1cmUAUkVRX0NsZWFyRmVhdHVyZQBSRVFfU2V0RGVzY3JpcHRvcgBVU0JfRGV2aWNlX0dldFN0YXR1cwBVU0JfRmVhdHVyZV9TZWxlY3RvcnNfdABVU0JfRGV2aWNlX0dldENvbmZpZ3VyYXRpb24ALi9sdWZhLW1hc3Rlci9MVUZBL0RyaXZlcnMvVVNCL0NvcmUvRGV2aWNlU3RhbmRhcmRSZXEuYwBSZXF1ZXN0SGVhZGVyQnl0ZQBHbG9iYWxJbnRTdGF0ZQBVU0JfRGV2aWNlX1NldERldmljZUFkZHJlc3MAUkVRX1N5bmNoRnJhbWUAVVNCX0RldmljZV9HZXRTZXJpYWxTdHJpbmcAVVNCX0RldmljZV9Qcm9jZXNzQ29udHJvbFJlcXVlc3QAVVNCX0RldmljZV9HZXREZXNjcmlwdG9yAEZFQVRVUkVfU0VMX0VuZHBvaW50SGFsdABVU0JfRGV2aWNlX1NldENvbmZpZ3VyYXRpb24AU2VyaWFsQnl0ZQBVU0JfRGV2aWNlX1NldEFkZHJlc3MARW5kcG9pbnRfUmVzZXREYXRhVG9nZ2xlAFNpZ1JlYWRBZGRyZXNzAEVuZHBvaW50X0NsZWFyU3RhbGwAR2xvYmFsSW50ZXJydXB0RGlzYWJsZQBEZXNjcmlwdG9yU2l6ZQBGRUFUVVJFX1NFTF9UZXN0TW9kZQBFbmRwb2ludF9Jc0VuYWJsZWQAUkVRX0dldENvbmZpZ3VyYXRpb24ARW5kcG9pbnRfV3JpdGVfMTZfTEUAVVNCX0RldmljZV9FbmFibGVEZXZpY2VBZGRyZXNzAEN1cnJlbnRTdGF0dXMAVVNCX0V2ZW50X1N0dWIALi9sdWZhLW1hc3Rlci9MVUZBL0RyaXZlcnMvVVNCL0NvcmUvRXZlbnRzLmMAVVNCX0RldmljZVRhc2sALi9sdWZhLW1hc3Rlci9MVUZBL0RyaXZlcnMvVVNCL0NvcmUvVVNCVGFzay5jAFByZXZFbmRwb2ludABFbmRwb2ludF9HZXRDdXJyZW50RW5kcG9pbnQASElEX1JFUV9HZXRSZXBvcnQAUmVwb3J0SU5TaXplAG1lbWNweQBISURfUkVRX1NldFByb3RvY29sAFN0YXRlc0NoYW5nZWQASElEX0NsYXNzUmVxdWVzdHNfdABtZW1jbXAASElEX1JFUE9SVF9JVEVNX0ZlYXR1cmUARm9yY2VTZW5kAEhJRF9SRVFfU2V0UmVwb3J0AC4vbHVmYS1tYXN0ZXIvTFVGQS9Ecml2ZXJzL1VTQi9DbGFzcy9EZXZpY2UvSElEQ2xhc3NEZXZpY2UuYwBSZXBvcnRJTkRhdGEASElEX1JFUE9SVF9JVEVNX0luAEhJRF9SZXBvcnRJdGVtVHlwZXNfdABISURfUkVQT1JUX0lURU1fT3V0AElkbGVQZXJpb2RFbGFwc2VkAEhJRF9SRVFfR2V0SWRsZQBISURfUkVRX1NldElkbGUA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cHRfQVZSOC5jAERldmljZVN0YW5kYXJkUmVxLmMARXZlbnRzLmMAVVNCVGFzay5jAEhJRENsYXNzRGV2aWNlLmMAZnB1dGMuYwBzcHJpbnRmLmMAX2V4aXQubwBfX3N0b3BfcHJvZ3JhbQBDQUxMQkFDS19BdWRpb19EZXZpY2VfR2V0U2V0RW5kcG9pbnRQcm9wZXJ0eQBDQUxMQkFDS19NU19EZXZpY2VfU0NTSUNvbW1hbmRSZWNlaXZlZABDQUxMQkFDS19BdWRpb19EZXZpY2VfR2V0U2V0SW50ZXJmYWNlUHJvcGVydHkAQ0FMTEJBQ0tfSElEUGFyc2VyX0ZpbHRlckhJRFJlcG9ydEl0ZW0AX192ZWN0b3JfMzgAX192ZWN0b3JfMjIAcmVtb3RlX2VuYWJsZV9zb21fdWFydABfX3ZlY3Rvcl8yOABfX3ZlY3Rvcl8xAEVWRU5UX1VTQl9EZXZpY2VfQ29uZmlndXJhdGlvbkNoYW5nZWQAVVNCX0luaXQAQ0FMTEJBQ0tfVVNCX0dldERlc2NyaXB0b3IAS2V5Ym9hcmRSZXBvcnQAcmVzcG9uc2UAVVNCX0lzSW5pdGlhbGl6ZWQAcmVtb3RlX2dldF9zdGF0dXMAX192ZWN0b3JfMzIAX19EQVRBX1JFR0lPTl9MRU5HVEhfXwBfX2VwaWxvZ3VlX3Jlc3RvcmVzX18AX19kaXZzZjMAaTJjX21hc3Rlcl93cml0ZQBVU0JfUmVzZXRJbnRlcmZhY2UAbWF0cml4X2NsZWFyAGFjdGl2ZV9tZXRhX21vZGUAX19URVhUX1JFR0lPTl9PUklHSU5fXwBleGVjdXRlX21ldGFfZnVuY3Rpb24AX19mcF9yb3VuZABfX3ZlY3Rvcl8zNABnZnhfZmx1c2gAX19tdWxoaV9jb25zdF8xMABfX2ZwX3NwbGl0MwBnZnhfY2xlYXIAX190cmFtcG9saW5lc19zdGFydABpMmNfbWFzdGVyX2luaXQAX19mcF9jbXAAcmVtb3RlX2Rpc2FibGVfc29tX3VhcnQARW5kcG9pbnRfUmVhZF9Db250cm9sX1N0cmVhbV9MRQBfZXRleHQAbWVudV9pdGVtcwBVU0JfRGV2aWNlX1Byb2Nlc3NDb250cm9sUmVxdWVzdABFbmRwb2ludF9Db25maWd1cmVFbmRwb2ludF9QcnYAX192ZWN0b3JfMjQAX192ZWN0b3JfMTIAcmVtb3RlX3R1cm5fb2ZmX2F1eABfX3VsdG9hX2ludmVydABFbmRwb2ludF9Xcml0ZV9Db250cm9sX1N0cmVhbV9MRQBFbmRwb2ludF9Db25maWd1cmVFbmRwb2ludFRhYmxlAEVuZHBvaW50X1dyaXRlX1N0cmVhbV9MRQBmb250AGtiZF9icmlnaHRuZXNzX2RlYwBfX2JhZF9pbnRlcnJ1cHQAbWVtY3B5AGdmeF9jb250cmFzdABrYmRfYnJpZ2h0bmVzc19pbmMAVVNCX0lOVF9DbGVhckFsbEludGVycnVwdHMAX19kYXRhX2xvYWRfZW5kAGFuaW1fZ29vZGJ5ZQByZW1vdGVfcmVwb3J0X3ZvbHRhZ2VzAHRlcm1feQBfX3ZlY3Rvcl82AEVWRU5UX1VTQl9EZXZpY2VfQ29ubmVjdABfX3ZlY3Rvcl8zMQBfX2xlc2YyAF9fdmVjdG9yXzM1AEVuZHBvaW50X0NsZWFyU3RhdHVzU3RhZ2UAX190cmFtcG9saW5lc19lbmQAX192ZWN0b3JfMzkAX192ZWN0b3JfMwBfX2ZwX3plcm8AZ2Z4X2NsZWFyX2ludmVydABlbXB0eV9zZXJpYWwAbWF0cml4X3JlbmRlcgBfX25lc2YyAF9fdmVjdG9yXzIzAF9fZGF0YV9sb2FkX3N0YXJ0AF9fZHRvcnNfZW5kAF9fYnNzX2VuZABVU0JfRGV2aWNlU3RhdGUAZGlzcGxheQBpMmNfc2xhdmVfYnVmZmVyAF9fdmVjdG9yXzMwAF9fTE9DS19SRUdJT05fTEVOR1RIX18Aa2JkX2JyaWdodG5lc3Nfc2V0AF9fdmVjdG9yXzI1AHN0cm5sZW4AQ0FMTEJBQ0tfSElEX0RldmljZV9Qcm9jZXNzSElEUmVwb3J0AFVTQl9EZXZpY2VfQ29uZmlndXJhdGlvbk51bWJlcgByZW1vdGVfd2FrZV9zb20AX19kaXZzZjN4AF9fdmVjdG9yXzExAEVWRU5UX1VTQl9EZXZpY2VfV2FrZVVwAF9fZnRvYV9lbmdpbmUAX19pbml0AG1hdHJpeF9zdGF0ZQBfX2d0c2YyAF9fdmVjdG9yXzEzAE1hbnVmYWN0dXJlclN0cmluZwBfX3ZlY3Rvcl8xNwBfX2ZwX25hbgBfX3ZlY3Rvcl8xOQBVU0JfRXZlbnRfU3R1YgBjdXJyZW50X21lbnVfeQBibGluawBFVkVOVF9VU0JfRGV2aWNlX1N1c3BlbmQAX192ZWN0b3JfNwBjdXJyZW50X3Njcm9sbF95AHJfaW5idWYAX19mcF9pbmYAcmVtb3RlX3R1cm5fb2ZmX3NvbQBfX2RvX2NsZWFyX2JzcwBzdHJubGVuX1AAX192ZWN0b3JfNDEAX19lZXByb21fZW5kAGV4ZWN1dGVfbWVudV9mdW5jdGlvbgBnZnhfcG9rZQBfX2Zsb2F0c2lzZgBfX3ZlY3RvcnMARVZFTlRfVVNCX0RldmljZV9TdGFydE9mRnJhbWUAZ2Z4X29uAEVWRU5UX1VTQl9EZXZpY2VfRGlzY29ubmVjdABfX3ZlY3Rvcl8yNwBfX2RhdGFfZW5kAFVTQl9JTlRfRGlzYWJsZUFsbEludGVycnVwdHMAc3RybmNweQBfX2Vxc2YyAGdmeF9pbnZlcnRfcm93AF9fdmVjdG9yX2RlZmF1bHQAX192ZWN0b3JfNQByZW1vdGVfcmVzZXRfc29tAF9fdmVjdG9yXzMzAFVTQl9EZXZpY2VfQ3VycmVudGx5U2VsZlBvd2VyZWQAbWVtY21wAF9fU0lHTkFUVVJFX1JFR0lPTl9MRU5HVEhfXwBVU0JfVVNCVGFzawBfX2N0b3JzX3N0YXJ0AEVuZHBvaW50X1dhaXRVbnRpbFJlYWR5AF9fdmVjdG9yXzM3AF9fZG9fY29weV9kYXRhAGdmeF9pbml0AF9fY21wc2YyAF9fZnBfcHNjQgBfX2ZwX3NwbGl0QQBnZnhfcG9rZV9zdHIAX19ic3Nfc3RhcnQAbWVtc2V0AG1haW4AX19sdHNmMgBfX3ZlY3Rvcl80AF9fREFUQV9SRUdJT05fT1JJR0lOX18ASElEX0RldmljZV9Qcm9jZXNzQ29udHJvbFJlcXVlc3QAbWF0cml4AEVWRU5UX1VTQl9EZXZpY2VfUmVzZXQAVVNCX0NvbnRyb2xSZXF1ZXN0AFNldHVwSGFyZHdhcmUAYW5pbV9oZWxsbwBfX2hlYXBfZW5kAHJlbW90ZV9yZWNlaXZlX3N0cmluZwBfX3ZlY3Rvcl85AHByb2Nlc3Nfa2V5Ym9hcmQAbG93X2JhdHRlcnlfYWxlcnQAX192ZWN0b3JfMgBfX1VTRVJfU0lHTkFUVVJFX1JFR0lPTl9MRU5HVEhfXwBzcHJpbnRmAF9fZ2VzZjIAa2JkX2JyaWdodG5lc3NfaW5pdABfX3ZlY3Rvcl8yMQBfX3ZlY3Rvcl8xNQBfX3ZlY3Rvcl8zNgBfX2ZwX3BzY0EARW5kcG9pbnRfV3JpdGVfQ29udHJvbF9QU3RyZWFtX0xFAEhJRF9EZXZpY2VfVVNCVGFzawBmcHV0YwBfX3ZlY3Rvcl8yOQBFVkVOVF9VU0JfRGV2aWNlX0NvbnRyb2xSZXF1ZXN0AHJlbW90ZV90dXJuX29uX3NvbQBfX2R0b3JzX3N0YXJ0AF9fY3RvcnNfZW5kAGluc2VydF9iYXRfaWNvbgBfX3N0YWNrAExhbmd1YWdlU3RyaW5nAF9fdmVjdG9yXzQwAF9lZGF0YQBfX3ZlY3Rvcl84AF9fdmVjdG9yXzI2AF9fZGl2c2YzX3BzZQBwd212YWwAaTJjX21hc3Rlcl9zdG9wAF9fZmxvYXR1bnNpc2YAQ0FMTEJBQ0tfSElEX0RldmljZV9DcmVhdGVISURSZXBvcnQAVVNCX0RldmljZV9SZW1vdGVXYWtldXBFbmFibGVkAG9sZWRicnQAYXRvaQB0ZXJtX3gARGV2aWNlRGVzY3JpcHRvcgBLZXlib2FyZF9ISURfSW50ZXJmYWNlAG1hdHJpeF9kZWJvdW5jZQBQcm9kdWN0U3RyaW5nAF9fRUVQUk9NX1JFR0lPTl9MRU5HVEhfXwBfZXhpdABpMmNfbWFzdGVyX3N0YXJ0AF9fdmVjdG9yXzE0AGxhc3RfbWV0YV9rZXkAX192ZWN0b3JfMTAAcmVtb3RlX2dldF92b2x0YWdlcwBfX3ZlY3Rvcl8xNgBfX2RhdGFfc3RhcnQAX192ZWN0b3JfMTgAQ29uZmlndXJhdGlvbkRlc2NyaXB0b3IASElEX0RldmljZV9Db25maWd1cmVFbmRwb2ludHMAX19GVVNFX1JFR0lPTl9MRU5HVEhfXwBfX1RFWFRfUkVHSU9OX0xFTkdUSF9fAF9fdmVjdG9yXzIwAF9fdmVjdG9yXzQyAGdmeF9vZmYAX19wcm9sb2d1ZV9zYXZlc19fAHZmcHJpbnRmAHJlbmRlcl9tZW51AHJlbW90ZV90dXJuX29uX2F1eABfX2ZwX3N6ZXJvAAAuc3ltdGFiAC5zdHJ0YWIALnNoc3RydGFiAC5kYXRhAC50ZXh0AC5ic3MALmNvbW1lbnQALm5vdGUuZ251LmF2ci5kZXZpY2VpbmZvAC5kZWJ1Z19hcmFuZ2VzAC5kZWJ1Z19pbmZvAC5kZWJ1Z19hYmJyZXYALmRlYnVnX2xpbmUALmRlYnVnX2ZyYW1lAC5kZWJ1Z19zdHIALmRlYnVnX2xvYwAuZGVidWdfcmFuZ2VzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbAAAAAQAAAAMAAAAAAYAAojkAAEgBAAAAAAAAAAAAAAEAAAAAAAAAIQAAAAEAAAAGAAAAAAAAAJQAAAAOOQAAAAAAAAAAAAACAAAAAAAAACcAAAAIAAAAAwAAAEgCgADqOgAA9QEAAAAAAAAAAAAAAQAAAAAAAAAsAAAAAQAAADAAAAAAAAAA6joAABEAAAAAAAAAAAAAAAEAAAABAAAANQAAAAcAAAAAAAAAAAAAAPw6AABAAAAAAAAAAAAAAAAEAAAAAAAAAE4AAAABAAAAAAAAAAAAAAA8OwAAgAQAAAAAAAAAAAAAAQAAAAAAAABdAAAAAQAAAAAAAAAAAAAAvD8AAL2HAAAAAAAAAAAAAAEAAAAAAAAAaQAAAAEAAAAAAAAAAAAAAHnHAACCIgAAAAAAAAAAAAABAAAAAAAAAHcAAAABAAAAAAAAAAAAAAD76QAAT0kAAAAAAAAAAAAAAQAAAAAAAACDAAAAAQAAAAAAAAAAAAAATDMBADQOAAAAAAAAAAAAAAQAAAAAAAAAkAAAAAEAAAAAAAAAAAAAAIBBAQA0LAAAAAAAAAAAAAABAAAAAAAAAJsAAAABAAAAAAAAAAAAAAC0bQEAl1cAAAAAAAAAAAAAAQAAAAAAAACmAAAAAQAAAAAAAAAAAAAAS8UBAMAFAAAAAAAAAAAAAAEAAAAAAAAAEQAAAAMAAAAAAAAAAAAAAMTvAQC0AAAAAAAAAAAAAAABAAAAAAAAAAEAAAACAAAAAAAAAAAAAAAMywEAQBUAABAAAAB6AAAABAAAABAAAAAJAAAAAwAAAAAAAAAAAAAATOABAHgPAAAAAAAAAAAAAAEAAAAAAAAA" diff --git a/reform2-keyboard-editor/mnt-reform-keyboard.js b/reform2-keyboard-editor/mnt-reform-keyboard.js @@ -0,0 +1,451 @@ + +var COLS = 14 +var ROWS = 6 + +var scancodes = { + "RESERVED":0x00, + "ERROR_ROLLOVER":0x01, + "POST_FAIL":0x02, + "ERROR_UNDEFINED":0x03, + "A":0x04, + "B":0x05, + "C":0x06, + "D":0x07, + "E":0x08, + "F":0x09, + "G":0x0A, + "H":0x0B, + "I":0x0C, + "J":0x0D, + "K":0x0E, + "L":0x0F, + "M":0x10, + "N":0x11, + "O":0x12, + "P":0x13, + "Q":0x14, + "R":0x15, + "S":0x16, + "T":0x17, + "U":0x18, + "V":0x19, + "W":0x1A, + "X":0x1B, + "Y":0x1C, + "Z":0x1D, + "1_AND_EXCLAMATION":0x1E, + "2_AND_AT":0x1F, + "3_AND_HASHMARK":0x20, + "4_AND_DOLLAR":0x21, + "5_AND_PERCENTAGE":0x22, + "6_AND_CARET":0x23, + "7_AND_AMPERSAND":0x24, + "8_AND_ASTERISK":0x25, + "9_AND_OPENING_PARENTHESIS":0x26, + "0_AND_CLOSING_PARENTHESIS":0x27, + "ENTER":0x28, + "ESCAPE":0x29, + "BACKSPACE":0x2A, + "TAB":0x2B, + "SPACE":0x2C, + "MINUS_AND_UNDERSCORE":0x2D, + "EQUAL_AND_PLUS":0x2E, + "OPENING_BRACKET_AND_OPENING_BRACE":0x2F, + "CLOSING_BRACKET_AND_CLOSING_BRACE":0x30, + "BACKSLASH_AND_PIPE":0x31, + "NON_US_HASHMARK_AND_TILDE":0x32, + "SEMICOLON_AND_COLON":0x33, + "APOSTROPHE_AND_QUOTE":0x34, + "GRAVE_ACCENT_AND_TILDE":0x35, + "COMMA_AND_LESS_THAN_SIGN":0x36, + "DOT_AND_GREATER_THAN_SIGN":0x37, + "SLASH_AND_QUESTION_MARK":0x38, + "CAPS_LOCK":0x39, + "F1":0x3A, + "F2":0x3B, + "F3":0x3C, + "F4":0x3D, + "F5":0x3E, + "F6":0x3F, + "F7":0x40, + "F8":0x41, + "F9":0x42, + "F10":0x43, + "F11":0x44, + "F12":0x45, + "PRINT_SCREEN":0x46, + "SCROLL_LOCK":0x47, + "PAUSE":0x48, + "INSERT":0x49, + "HOME":0x4A, + "PAGE_UP":0x4B, + "DELETE":0x4C, + "END":0x4D, + "PAGE_DOWN":0x4E, + "RIGHT_ARROW":0x4F, + "LEFT_ARROW":0x50, + "DOWN_ARROW":0x51, + "UP_ARROW":0x52, + "NUM_LOCK":0x53, + "KEYPAD_SLASH":0x54, + "KEYPAD_ASTERISK":0x55, + "KEYPAD_MINUS":0x56, + "KEYPAD_PLUS":0x57, + "KEYPAD_ENTER":0x58, + "KEYPAD_1_AND_END":0x59, + "KEYPAD_2_AND_DOWN_ARROW":0x5A, + "KEYPAD_3_AND_PAGE_DOWN":0x5B, + "KEYPAD_4_AND_LEFT_ARROW":0x5C, + "KEYPAD_5":0x5D, + "KEYPAD_6_AND_RIGHT_ARROW":0x5E, + "KEYPAD_7_AND_HOME":0x5F, + "KEYPAD_8_AND_UP_ARROW":0x60, + "KEYPAD_9_AND_PAGE_UP":0x61, + "KEYPAD_0_AND_INSERT":0x62, + "KEYPAD_DOT_AND_DELETE":0x63, + "NON_US_BACKSLASH_AND_PIPE":0x64, + "APPLICATION":0x65, + "POWER":0x66, + "KEYPAD_EQUAL_SIGN":0x67, + "F13":0x68, + "F14":0x69, + "F15":0x6A, + "F16":0x6B, + "F17":0x6C, + "F18":0x6D, + "F19":0x6E, + "F20":0x6F, + "F21":0x70, + "F22":0x71, + "F23":0x72, + "F24":0x73, + "EXECUTE":0x74, + "HELP":0x75, + "MENU":0x76, + "SELECT":0x77, + "STOP":0x78, + "AGAIN":0x79, + "UNDO":0x7A, + "CUT":0x7B, + "COPY":0x7C, + "PASTE":0x7D, + "FIND":0x7E, + "MUTE":0x7F, + "VOLUME_UP":0x80, + "VOLUME_DOWN":0x81, + "LOCKING_CAPS_LOCK":0x82, + "LOCKING_NUM_LOCK":0x83, + "LOCKING_SCROLL_LOCK":0x84, + "KEYPAD_COMMA":0x85, + "KEYPAD_EQUAL_SIGN_AS400":0x86, + "INTERNATIONAL1":0x87, + "INTERNATIONAL2":0x88, + "INTERNATIONAL3":0x89, + "INTERNATIONAL4":0x8A, + "INTERNATIONAL5":0x8B, + "INTERNATIONAL6":0x8C, + "INTERNATIONAL7":0x8D, + "INTERNATIONAL8":0x8E, + "INTERNATIONAL9":0x8F, + "LANG1":0x90, + "LANG2":0x91, + "LANG3":0x92, + "LANG4":0x93, + "LANG5":0x94, + "LANG6":0x95, + "LANG7":0x96, + "LANG8":0x97, + "LANG9":0x98, + "ALTERNATE_ERASE":0x99, + "SYSREQ":0x9A, + "CANCEL":0x9B, + "CLEAR":0x9C, + "PRIOR":0x9D, + "RETURN":0x9E, + "SEPARATOR":0x9F, + "OUT":0xA0, + "OPER":0xA1, + "CLEAR_AND_AGAIN":0xA2, + "CRSEL_AND_PROPS":0xA3, + "EXSEL":0xA4, + "KEYPAD_00":0xB0, + "KEYPAD_000":0xB1, + "THOUSANDS_SEPARATOR":0xB2, + "DECIMAL_SEPARATOR":0xB3, + "CURRENCY_UNIT":0xB4, + "CURRENCY_SUB_UNIT":0xB5, + "KEYPAD_OPENING_PARENTHESIS":0xB6, + "KEYPAD_CLOSING_PARENTHESIS":0xB7, + "KEYPAD_OPENING_BRACE":0xB8, + "KEYPAD_CLOSING_BRACE":0xB9, + "KEYPAD_TAB":0xBA, + "KEYPAD_BACKSPACE":0xBB, + "KEYPAD_A":0xBC, + "KEYPAD_B":0xBD, + "KEYPAD_C":0xBE, + "KEYPAD_D":0xBF, + "KEYPAD_E":0xC0, + "KEYPAD_F":0xC1, + "KEYPAD_XOR":0xC2, + "KEYPAD_CARET":0xC3, + "KEYPAD_PERCENTAGE":0xC4, + "KEYPAD_LESS_THAN_SIGN":0xC5, + "KEYPAD_GREATER_THAN_SIGN":0xC6, + "KEYPAD_AMP":0xC7, + "KEYPAD_AMP_AMP":0xC8, + "KEYPAD_PIPE":0xC9, + "KEYPAD_PIPE_PIPE":0xCA, + "KEYPAD_COLON":0xCB, + "KEYPAD_HASHMARK":0xCC, + "KEYPAD_SPACE":0xCD, + "KEYPAD_AT":0xCE, + "KEYPAD_EXCLAMATION_SIGN":0xCF, + "KEYPAD_MEMORY_STORE":0xD0, + "KEYPAD_MEMORY_RECALL":0xD1, + "KEYPAD_MEMORY_CLEAR":0xD2, + "KEYPAD_MEMORY_ADD":0xD3, + "KEYPAD_MEMORY_SUBTRACT":0xD4, + "KEYPAD_MEMORY_MULTIPLY":0xD5, + "KEYPAD_MEMORY_DIVIDE":0xD6, + "KEYPAD_PLUS_AND_MINUS":0xD7, + "KEYPAD_CLEAR":0xD8, + "KEYPAD_CLEAR_ENTRY":0xD9, + "KEYPAD_BINARY":0xDA, + "KEYPAD_OCTAL":0xDB, + "KEYPAD_DECIMAL":0xDC, + "KEYPAD_HEXADECIMAL":0xDD, + "LEFT_CONTROL":0xE0, + "LEFT_SHIFT":0xE1, + "LEFT_ALT":0xE2, + "LEFT_GUI":0xE3, + "RIGHT_CONTROL":0xE4, + "RIGHT_SHIFT":0xE5, + "RIGHT_ALT":0xE6, + "RIGHT_GUI":0xE7, + "MEDIA_PLAY":0xE8, + "MEDIA_STOP":0xE9, + "MEDIA_PREVIOUS_TRACK":0xEA, + "MEDIA_NEXT_TRACK":0xEB, + "MEDIA_EJECT":0xEC, + "MEDIA_VOLUME_UP":0xED, + "MEDIA_VOLUME_DOWN":0xEE, + "MEDIA_MUTE":0xEF, + "MEDIA_WWW":0xF0, + "MEDIA_BACKWARD":0xF1, + "MEDIA_FORWARD":0xF2, + "MEDIA_CANCEL":0xF3, + "MEDIA_SEARCH":0xF4, + "MEDIA_SLEEP":0xF8, + "MEDIA_LOCK":0xF9, + "MEDIA_RELOAD":0xFA, + "MEDIA_CALCULATOR":0xFB +} + +var engravings = { + "ESCAPE": "ESC", + "EXSEL": "◯", + "BACKSPACE": "⌫", + "DELETE": "DEL", + "MINUS_AND_UNDERSCORE": "- _", + "EQUAL_AND_PLUS": "= +", + "OPENING_BRACKET_AND_OPENING_BRACE": "[ {", + "CLOSING_BRACKET_AND_CLOSING_BRACE": "] }", + "BACKSLASH_AND_PIPE": "\\ |", + "NON_US_HASHMARK_AND_TILDE": "# ~", + "NON_US_BACKSLASH_AND_PIPE": "\\ |", + "SEMICOLON_AND_COLON": "; :", + "APOSTROPHE_AND_QUOTE": "' \"", + "GRAVE_ACCENT_AND_TILDE": "` ~", + "COMMA_AND_LESS_THAN_SIGN": ", <", + "DOT_AND_GREATER_THAN_SIGN": ". >", + "SLASH_AND_QUESTION_MARK": "/ ?", + + "1_AND_EXCLAMATION": "1 !", + "2_AND_AT": "2 @", + "3_AND_HASHMARK": "3 #", + "4_AND_DOLLAR": "4 $", + "5_AND_PERCENTAGE": "5 %", + "6_AND_CARET": "6 ^", + "7_AND_AMPERSAND": "7 &", + "8_AND_ASTERISK": "8 *", + "9_AND_OPENING_PARENTHESIS": "9 (", + "0_AND_CLOSING_PARENTHESIS": "0 )", + + "LEFT_CONTROL": "CTRL (L)", + "RIGHT_CONTROL": "CTRL (R)", + "LEFT_SHIFT": "SHIFT (L)", + "RIGHT_SHIFT": "SHIFT (R)", + "LEFT_ALT": "ALT (L)", + "RIGHT_ALT": "ALT (R)", + "LEFT_GUI": "SUPER (L)", + "RIGHT_GUI": "SUPER (R)", + "APPLICATION": "…", + + "RIGHT_ARROW": "→", + "LEFT_ARROW": "←", + "UP_ARROW": "↑", + "DOWN_ARROW": "↓", + "PAGE_UP": "PGUP", + "PAGE_DOWN": "PGDN", +} + +var customKeyboard = { + title: "MNT Reform QWERTY-US", + matrix: [ + "ESCAPE", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "EXSEL", + + "GRAVE_ACCENT_AND_TILDE", "1_AND_EXCLAMATION", "2_AND_AT", "3_AND_HASHMARK", "4_AND_DOLLAR", "5_AND_PERCENTAGE", "6_AND_CARET", "7_AND_AMPERSAND", "8_AND_ASTERISK", "9_AND_OPENING_PARENTHESIS", "0_AND_CLOSING_PARENTHESIS", "MINUS_AND_UNDERSCORE", "EQUAL_AND_PLUS", "BACKSPACE", + + "TAB", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "OPENING_BRACKET_AND_OPENING_BRACE", "CLOSING_BRACKET_AND_CLOSING_BRACE", "BACKSLASH_AND_PIPE", + + "LEFT_CONTROL", "APPLICATION", "A", "S", "D", "F", "G", "H", "J", "K", "L", "SEMICOLON_AND_COLON", "APOSTROPHE_AND_QUOTE", "ENTER", + + "LEFT_SHIFT", "DELETE", "Z", "X", "C", "V", "B", "N", "M", "COMMA_AND_LESS_THAN_SIGN", "DOT_AND_GREATER_THAN_SIGN", "SLASH_AND_QUESTION_MARK", "UP_ARROW", "RIGHT_SHIFT", + + "RIGHT_GUI", "LEFT_GUI", "RIGHT_CONTROL", "SPACE", "LEFT_ALT", "RIGHT_ALT", "SPACE", "PAGE_UP", "PAGE_DOWN", "LEFT_ARROW", "DOWN_ARROW", "RIGHT_ARROW" + ] +} + +function getKey(idx) { + return document.getElementsByClassName("kbd-key")[idx] +} + +function getKeyIdx(key) { + return key.id.split("key-")[1] +} + +function getSelectedKey() { + return document.getElementsByClassName("selected")[0] +} + +function deselectKeys() { + var allKeys = document.getElementsByClassName("kbd-key") + for (k of allKeys) { + k.classList.remove("selected") + } +} + +var swapMode = false + +function enableSwapMode() { + document.getElementById("swap-message").innerHTML = "Now click on a key to swap with selected key." + swapMode = true +} + +function disableSwapMode() { + document.getElementById("swap-message").innerHTML = "" + swapMode = false +} + +function selectKey() { + if (swapMode) { + disableSwapMode() + + var swapKey = getSelectedKey() + var swapIdx = getKeyIdx(swapKey) + var idx = getKeyIdx(this) + + var swapKeyCode = customKeyboard.matrix[swapIdx] + customKeyboard.matrix[swapIdx] = customKeyboard.matrix[idx] + customKeyboard.matrix[idx] = swapKeyCode + renderKeyboard(customKeyboard) + } + deselectKeys() + this.classList.add("selected") + applyKeyToSettings() +} + +function selectKeyEl(el) { + deselectKeys() + el.classList.add("selected") + applyKeyToSettings() +} + +function applySettingsToKey() { + var selectedKey = getSelectedKey() + var idx = getKeyIdx(selectedKey) + + var scanCodeName = document.getElementById("key-scancodename").value + customKeyboard.matrix[idx] = scanCodeName + + renderKeyboard(customKeyboard) +} + +function applyKeyToSettings() { + var selectedKey = getSelectedKey() + var idx = getKeyIdx(selectedKey) + + document.getElementById("key-scancodename").value = customKeyboard.matrix[idx] +} + +function populateSettingsForm() { + var scancodeEl = document.getElementById("key-scancodes") + var html = "" + for ([k,v] of Object.entries(scancodes)) { + html+="<option value='"+k+"'>Code: "+v+"</option>" + } + scancodeEl.innerHTML = html +} + +function renderKeyboard(kbd) { + document.getElementById("title").value = kbd.title + + var rows = document.getElementsByClassName("kbd-row") + var defaultKeys = kbd.matrix + + for (var y=0; y<rows.length; y++) { + var row = rows[y] + var cols = rows[y].getElementsByClassName("kbd-key") + for (var x=0; x<cols.length; x++) { + var col = cols[x] + var idx = y*COLS+x + var key = defaultKeys[idx] + + if (engravings[key]) { + col.innerHTML = engravings[key] + } else { + col.innerHTML = key + } + col.id = "key-"+idx + + col.onclick = selectKey + } + } +} + +function generateFirmware() { + var fw = Base64Binary.decode(defaultFirmware) + var idx = 0 + for (var i=0; i<fw.length-3; i++) { + if (fw[i]==0xfe && fw[i+1]==0xed && fw[i+2]==0xca && fw[i+3]==0xfe) { + console.log("magic number found at",i) + idx = i-14*6+2 + console.log("first keycodes in matrix:",fw[idx],fw[idx+1],fw[idx+2],fw[idx+3]) + break + } + } + + if (idx) { + // patch the firmware! + for (var i=0; i<14*6-2; i++) { + sc = scancodes[customKeyboard.matrix[i]] + fw[idx+i] = sc + + if (!sc) { + alert("Warning: No scancode for key "+customKeyboard.matrix[i]) + } + } + + var blob = new Blob([fw], {type: "application/octet-stream"}) + var link = document.createElement('a') + link.href = window.URL.createObjectURL(blob) + link.download = "Keyboard.elf" + link.click() + } +} + +function initKeyboard() { + populateSettingsForm() + renderKeyboard(customKeyboard) + selectKeyEl(getKey(0)) +} diff --git a/reform2-keyboard-editor/refkbd.html b/reform2-keyboard-editor/refkbd.html @@ -0,0 +1,156 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"/> + <title>MNT Reform Keyboard Editor</title> + <link rel="stylesheet" href="style.css"></link> + <script src="base64binary.js"></script> + <script src="mnt-reform-keyboard-firmware.js"></script> + <script src="mnt-reform-keyboard.js"></script> +</head> +<body onload="initKeyboard()"> +<section> + <h1>MNT Reform Keyboard Editor</h1> + <h2>Layout</h2> + + <div class="keyboard"> + <div class="kbd-row"> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key key-1-5"></div> + </div> + + <div class="kbd-row"> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key key-1-5"></div> + </div> + + <div class="kbd-row"> + <div class="kbd-key key-1-5"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + </div> + + <div class="kbd-row"> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key key-1-5"></div> + </div> + + <div class="kbd-row"> + <div class="kbd-key key-1-5"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + </div> + + <div class="kbd-row last-row"> + <div class="kbd-key key-1-5"></div> + <div class="kbd-key key-1-5"></div> + <div class="kbd-key key-1-5"></div> + <div class="kbd-key key-1-5"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key key-1-5"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + <div class="kbd-key"></div> + </div> + </div> + +</section> +<section> + <h2>Key <span id="keyid"></span></h2> + <div> + <label> + Scancode: + <input id="key-scancodename" list="key-scancodes" onchange="applySettingsToKey()"> + <datalist id="key-scancodes"></datalist> + </label> + </div> + <div> + <button onclick="enableSwapMode()">Swap with Key…</button> + <span id="swap-message"></span> + </div> +</section> +<section> + <h2>Export</h2> + <div> + <label> + Title: + <input id="title" type="text" value="" placeholder="Title"> + </label> + </div> +</section> +<section> + <h2>Instructions</h2> + <button onclick="generateFirmware()">Download Customized Firmware</button> + <p> + After downloading the Keyboard.elf file, flash it like this: + </p> + <code> + objcopy -O ihex Keyboard.elf Keyboard.hex<br> + dfu-programmer atmega32u4 erase --suppress-bootloader-mem<br> + dfu-programmer atmega32u4 flash ./Keyboard.hex --suppress-bootloader-mem<br> + dfu-programmer atmega32u4 start + </code> +</section> +</body> +</html> diff --git a/reform2-keyboard-editor/style.css b/reform2-keyboard-editor/style.css @@ -0,0 +1,75 @@ +@import url('inter_ui_webfont/inter-ui.css'); + +* { font-family: 'Inter UI', sans-serif; } + +html { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + +body { + margin: 40px; +} + +h1 { + font-size: 75px; + font-weight: 800; + margin-left: -3px; + line-height: 1.0; + margin-bottom: 0; + margin-top: 0; +} + +h2 { + font-size: 34px; + font-weight: 800; + margin-bottom: 18px; +} + +h3 { + font-size: 18px; + font-weight: 800; + margin-bottom: 1em; +} + +section > div { + margin-bottom: 1em; +} + +.kbd-key { + display: inline-block; + width: 60px; + height: 55px; + margin-right: 4px; + margin-bottom: 4px; + font-size: 14px; + max-width: 60px; + overflow: hidden; + overflow-wrap: break-word; + padding-top: 5px; + text-align: center; + + border: 1px solid black; + border-radius: 3px; + box-shadow: 0px 2px 4px rgb(0 0 0 / 25%); +} + +.kbd-key.key-1-5 { + width: 90px; + max-width: 90px; +} + +.last-row .kbd-key.key-1-5 { + margin-right: 8.3px; +} + +.kbd-key.selected { + background-color: black; + color: white; +} + +input, button { + font-size: 14pt; +} diff --git a/reform2-keyboard-fw/Descriptors.c b/reform2-keyboard-fw/Descriptors.c @@ -1,219 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2018. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaims all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * - * USB Device Descriptors, for library use when in USB device mode. Descriptors are special - * computer-readable structures which the host requests upon device enumeration, to determine - * the device's capabilities and functions. - */ - -#include "Config/LUFAConfig.h" - -#include "Descriptors.h" - - -/** HID class report descriptor. This is a special descriptor constructed with values from the - * USBIF HID class specification to describe the reports and capabilities of the HID device. This - * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) - * the device will send, and what it may be sent back from the host. Refer to the HID specification for - * more details on HID report descriptors. - */ -const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = -{ - /* Use the HID class driver's standard Keyboard report. - * Max simultaneous keys: 6 - */ - HID_DESCRIPTOR_KEYBOARD(6) -}; - -/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall - * device characteristics, including the supported USB version, control endpoint size and the - * number of device configurations. The descriptor is read out by the USB host when the enumeration - * process begins. - */ -const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = -{ - .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, - - .USBSpecification = VERSION_BCD(1,1,0), - .Class = USB_CSCP_NoDeviceClass, - .SubClass = USB_CSCP_NoDeviceSubclass, - .Protocol = USB_CSCP_NoDeviceProtocol, - - .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, - - .VendorID = 0x03EB, - .ProductID = 0x2042, - .ReleaseNumber = VERSION_BCD(0,0,1), - - .ManufacturerStrIndex = STRING_ID_Manufacturer, - .ProductStrIndex = STRING_ID_Product, - .SerialNumStrIndex = NO_DESCRIPTOR, - - .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS -}; - -/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage - * of the device in one of its supported configurations, including information about any device interfaces - * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting - * a configuration so that the host may correctly communicate with the USB device. - */ -const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = -{ - .Config = - { - .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, - - .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), - .TotalInterfaces = 1, - - .ConfigurationNumber = 1, - .ConfigurationStrIndex = NO_DESCRIPTOR, - - .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED), - - .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) - }, - - .HID_Interface = - { - .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, - - .InterfaceNumber = INTERFACE_ID_Keyboard, - .AlternateSetting = 0x00, - - .TotalEndpoints = 1, - - .Class = HID_CSCP_HIDClass, - .SubClass = HID_CSCP_BootSubclass, - .Protocol = HID_CSCP_KeyboardBootProtocol, - - .InterfaceStrIndex = NO_DESCRIPTOR - }, - - .HID_KeyboardHID = - { - .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, - - .HIDSpec = VERSION_BCD(1,1,1), - .CountryCode = 0x00, - .TotalReportDescriptors = 1, - .HIDReportType = HID_DTYPE_Report, - .HIDReportLength = sizeof(KeyboardReport) - }, - - .HID_ReportINEndpoint = - { - .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, - - .EndpointAddress = KEYBOARD_EPADDR, - .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), - .EndpointSize = KEYBOARD_EPSIZE, - .PollingIntervalMS = 0x05 - }, -}; - -/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests - * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate - * via the language ID table available at USB.org what languages the device supports for its string descriptors. - */ -const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG); - -/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable - * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device - * Descriptor. - */ -const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(L"MNT"); - -/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, - * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device - * Descriptor. - */ -const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Reform Keyboard"); - -/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" - * documentation) by the application code so that the address and size of a requested descriptor can be given - * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function - * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the - * USB host. - */ -uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, - const uint16_t wIndex, - const void** const DescriptorAddress) -{ - const uint8_t DescriptorType = (wValue >> 8); - const uint8_t DescriptorNumber = (wValue & 0xFF); - - const void* Address = NULL; - uint16_t Size = NO_DESCRIPTOR; - - switch (DescriptorType) - { - case DTYPE_Device: - Address = &DeviceDescriptor; - Size = sizeof(USB_Descriptor_Device_t); - break; - case DTYPE_Configuration: - Address = &ConfigurationDescriptor; - Size = sizeof(USB_Descriptor_Configuration_t); - break; - case DTYPE_String: - switch (DescriptorNumber) - { - case STRING_ID_Language: - Address = &LanguageString; - Size = pgm_read_byte(&LanguageString.Header.Size); - break; - case STRING_ID_Manufacturer: - Address = &ManufacturerString; - Size = pgm_read_byte(&ManufacturerString.Header.Size); - break; - case STRING_ID_Product: - Address = &ProductString; - Size = pgm_read_byte(&ProductString.Header.Size); - break; - } - - break; - case HID_DTYPE_HID: - Address = &ConfigurationDescriptor.HID_KeyboardHID; - Size = sizeof(USB_HID_Descriptor_HID_t); - break; - case HID_DTYPE_Report: - Address = &KeyboardReport; - Size = sizeof(KeyboardReport); - break; - } - - *DescriptorAddress = Address; - return Size; -} - diff --git a/reform2-keyboard-fw/Descriptors.h b/reform2-keyboard-fw/Descriptors.h @@ -1,93 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2018. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaims all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * - * Header file for Descriptors.c. - */ - -#ifndef _DESCRIPTORS_H_ -#define _DESCRIPTORS_H_ - - /* Includes: */ - #include <avr/pgmspace.h> - - #include <LUFA/Drivers/USB/USB.h> - - /* Type Defines: */ - /** Type define for the device configuration descriptor structure. This must be defined in the - * application code, as the configuration descriptor contains several sub-descriptors which - * vary between devices, and which describe the device's usage to the host. - */ - typedef struct - { - USB_Descriptor_Configuration_Header_t Config; - - // Keyboard HID Interface - USB_Descriptor_Interface_t HID_Interface; - USB_HID_Descriptor_HID_t HID_KeyboardHID; - USB_Descriptor_Endpoint_t HID_ReportINEndpoint; - } USB_Descriptor_Configuration_t; - - /** Enum for the device interface descriptor IDs within the device. Each interface descriptor - * should have a unique ID index associated with it, which can be used to refer to the - * interface from other descriptors. - */ - enum InterfaceDescriptors_t - { - INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */ - }; - - /** Enum for the device string descriptor IDs within the device. Each string descriptor should - * have a unique ID index associated with it, which can be used to refer to the string from - * other descriptors. - */ - enum StringDescriptors_t - { - STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ - STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ - STRING_ID_Product = 2, /**< Product string ID */ - }; - - /* Macros: */ - /** Endpoint address of the Keyboard HID reporting IN endpoint. */ - #define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1) - - /** Size in bytes of the Keyboard HID reporting IN endpoint. */ - #define KEYBOARD_EPSIZE 8 - - /* Function Prototypes: */ -//uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, -// const uint16_t wIndex, -// const void** const DescriptorAddress) -// ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); - -#endif - diff --git a/reform2-keyboard-fw/Keyboard.c b/reform2-keyboard-fw/Keyboard.c @@ -1,1067 +0,0 @@ -/* - MNT Reform 2.0 Keyboard Firmware - Copyright 2019-2021 Lukas F. Hartmann / MNT Research GmbH, Berlin - lukas@mntre.com -*/ -/* - LUFA Library - Copyright (C) Dean Camera, 2018. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ -/* - Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaims all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -#include "Config/LUFAConfig.h" -#include "Keyboard.h" -#include <avr/io.h> -#include "LUFA/Drivers/Peripheral/Serial.h" -#include "ssd1306.h" -#include "scancodes.h" -#include <stdlib.h> -#include <avr/sleep.h> - -#define KBD_FW_REV "R1 20210927" -//#define KBD_VARIANT_STANDALONE -#define KBD_VARIANT_QWERTY_US -//#define KBD_VARIANT_NEO2 - -#define COLS 14 -#define ROWS 6 - -uint8_t matrix[COLS*6+2] = { - KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, HID_KEYBOARD_SC_EXSEL, - - KEY_GRAVE_ACCENT_AND_TILDE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS_AND_UNDERSCORE, KEY_EQUAL_AND_PLUS, KEY_BACKSPACE, - - KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_OPENING_BRACKET_AND_OPENING_BRACE, KEY_CLOSING_BRACKET_AND_CLOSING_BRACE, KEY_BACKSLASH_AND_PIPE, - - HID_KEYBOARD_SC_LEFT_CONTROL, HID_KEYBOARD_SC_APPLICATION, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON_AND_COLON, KEY_APOSTROPHE_AND_QUOTE, KEY_ENTER, - - HID_KEYBOARD_SC_LEFT_SHIFT, HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN, HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN, KEY_SLASH_AND_QUESTION_MARK, HID_KEYBOARD_SC_UP_ARROW, HID_KEYBOARD_SC_RIGHT_SHIFT, - - HID_KEYBOARD_SC_RIGHT_GUI, HID_KEYBOARD_SC_LEFT_GUI, HID_KEYBOARD_SC_RIGHT_CONTROL, KEY_SPACE, HID_KEYBOARD_SC_LEFT_ALT, HID_KEYBOARD_SC_RIGHT_ALT, KEY_SPACE, HID_KEYBOARD_SC_PAGE_UP, HID_KEYBOARD_SC_PAGE_DOWN, HID_KEYBOARD_SC_LEFT_ARROW, HID_KEYBOARD_SC_DOWN_ARROW, HID_KEYBOARD_SC_RIGHT_ARROW, 0xfe,0xed,0xca,0xfe -}; - -/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */ -static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)]; - -/** LUFA HID Class driver interface configuration and state information. This structure is - * passed to all HID Class driver functions, so that multiple instances of the same class - * within a device can be differentiated from one another. - */ -USB_ClassInfo_HID_Device_t Keyboard_HID_Interface = - { - .Config = - { - .InterfaceNumber = INTERFACE_ID_Keyboard, - .ReportINEndpoint = - { - .Address = KEYBOARD_EPADDR, - .Size = KEYBOARD_EPSIZE, - .Banks = 1, - }, - .PrevReportINBuffer = PrevKeyboardHIDReportBuffer, - .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer), - }, - }; - - -#define output_low(port,pin) port &= ~(1<<pin) -#define output_high(port,pin) port |= (1<<pin) -#define set_input(portdir,pin) portdir &= ~(1<<pin) -#define set_output(portdir,pin) portdir |= (1<<pin) - -uint8_t matrix_debounce[COLS*6]; -uint8_t matrix_state[COLS*6]; -uint8_t remote_som_power_expected_state = 0; - -// f8 = sleep -// 49 = mute -// 84 = scroll lock - -char r_inbuf[10]; - -void gfx_clear(void) { - for (int y=0; y<4; y++) { - for (int x=0; x<21; x++) { - gfx_poke(x,y,' '); - } - } - gfx_clear_invert(); -} - -void empty_serial(void) { - int clock = 0; - while (Serial_ReceiveByte()>=0 && clock<100) { - // flush serial - clock++; - } -} - -int term_x = 0; -int term_y = 0; - -char response[64]; - -int remote_receive_string(int print) { - char done = 0; - int32_t clock = 0; - int res_x = 0; - response[0] = 0; - - while (!done) { - int16_t chr = -1; - clock = 0; - while (chr==-1 || chr==0) { - chr=Serial_ReceiveByte(); - clock++; - if (clock>500000) goto timeout; - } - int poke_chr = chr; - if (chr=='\n') poke_chr=' '; - if (chr!='\r') { - if (print) { - gfx_poke(term_x,term_y,poke_chr); - gfx_poke(term_x+1,term_y,' '); - term_x++; - if (term_x>=20) { - term_x=0; - term_y++; - if (term_y>=3) { - term_y=0; - } - } - } - if (res_x<63) { - response[res_x++] = chr; - response[res_x] = 0; - } - } - if (chr=='\r') done = 1; - } -timeout: - if (!done && print) gfx_poke(20,0,'T'); - empty_serial(); - if (print) { - gfx_flush(); - } - return done; -} - -void anim_hello(void) { - gfx_clear(); - gfx_on(); - for (int y=0; y<3; y++) { - for (int x=0; x<12; x++) { - gfx_poke(x+4,y+1,(5+y)*32+x); - gfx_flush(); - } - } - for (int y=0; y<0xff; y++) { - gfx_contrast(y); - Delay_MS(2); - } - for (int y=0; y<0xff; y++) { - gfx_contrast(0xff-y); - Delay_MS(2); - } -} - -void anim_goodbye(void) { - gfx_clear(); - gfx_on(); - for (int y=0; y<3; y++) { - for (int x=0; x<12; x++) { - gfx_poke(x+4,y+1,(5+y)*32+x); - } - } - for (int y=0; y<3; y++) { - for (int x=0; x<12; x++) { - gfx_poke(x+4,y+1,' '); - gfx_flush(); - } - } - gfx_off(); -} - -float voltages[8]; - -void insert_bat_icon(char* str, int x, float v) { - char icon = 0; - if (v>=3.3) { - icon = 8; - } else if (v>=3.1) { - icon = 6; - } else if (v>=3.0) { - icon = 4; - } else if (v>=2.9) { - icon = 2; - } else { - icon = 0; - } - str[x] = 4*32+icon; - str[x+1] = 4*32+icon+1; -} - -void remote_try_wakeup(void) { - char buf[64]; - - for (int i=0; i<1000; i++) { - if (i%10 == 0) { - gfx_clear(); - sprintf(buf, "Waking up LPC... %d%%", i/4); - gfx_poke_str(0, 0, buf); - gfx_flush(); - } - - Serial_SendByte('a'); - Serial_SendByte('\r'); - - if (Serial_ReceiveByte()>0) { - remote_receive_string(0); - break; - } - - Delay_MS(25); - } - Serial_SendByte('\r'); - Delay_MS(10); - while (remote_receive_string(0)) { - Delay_MS(25); - } -} - -int remote_try_command(char* cmd, int print_response) { - int ok = 0; - - empty_serial(); - for (int tries=0; tries<2; tries++) { - for (int i=0; i<strlen(cmd); i++) { - Serial_SendByte(cmd[i]); - } - Serial_SendByte('\r'); - Delay_MS(1); - - if (print_response) { - term_x = 0; - term_y = 0; - } - ok = remote_receive_string(print_response); - - if (!ok && tries == 0) { - remote_try_wakeup(); - empty_serial(); - } - if (ok) break; - } - if (!ok) { - gfx_clear(); - gfx_poke_str(0, 0, "No response from LPC."); - gfx_flush(); - } - - empty_serial(); - return ok; -} - -void remote_get_voltages(void) { - term_x = 0; - term_y = 0; - - float bat_volts = 0; - float bat_amps = 0; - char bat_gauge[5] = {0,0,0,0,0}; - - int ok = remote_try_command("c", 0); - if (!ok) return; - - // lpc format: 32 32 32 32 32 32 32 32 mA 0256mV26143 ???% P1 - // | | | | | | | | | | | | | - // 0 3 6 9 12 15 18 21 24| | | | - // 26 33 39 44 - // | - // `- can be a minus - float sum_volts = 0; - - for (int i=0; i<8; i++) { - voltages[i] = ((float)((response[i*3]-'0')*10 + (response[i*3+1]-'0')))/10.0; - if (voltages[i]<0) voltages[i]=0; - if (voltages[i]>=10) voltages[i]=9.9; - sum_volts += voltages[i]; - } - - int amps_offset = 3*8+2; - // cut off string - response[amps_offset+5]=0; - bat_amps = ((float)atoi(&response[amps_offset]))/1000.0; - int volts_offset = amps_offset+5+2; - response[volts_offset+5]=0; - bat_volts = ((float)atoi(&response[volts_offset]))/1000.0; - int gauge_offset = volts_offset+5+1; - strncpy(bat_gauge, &response[gauge_offset], 4); - - char* power_str = " "; - int syspower_offset = gauge_offset+5; - char power_digit = response[syspower_offset+1]; - if (power_digit == '1') { - power_str = " On"; - } else if (power_digit == '0') { - power_str = "Off"; - } - - // plot - gfx_clear(); - char str[32]; - - sprintf(str,"[] %.1f [] %.1f %s",voltages[0],voltages[4],bat_gauge); - insert_bat_icon(str,0,voltages[0]); - insert_bat_icon(str,8,voltages[4]); - gfx_poke_str(0,0,str); - - sprintf(str,"[] %.1f [] %.1f %s",voltages[1],voltages[5],power_str); - insert_bat_icon(str,0,voltages[1]); - insert_bat_icon(str,8,voltages[5]); - gfx_poke_str(0,1,str); - - if (bat_amps>=0) { - sprintf(str,"[] %.1f [] %.1f %2.3fA",voltages[2],voltages[6],bat_amps); - } else { - sprintf(str,"[] %.1f [] %.1f %2.2fA",voltages[2],voltages[6],bat_amps); - } - insert_bat_icon(str,0,voltages[2]); - insert_bat_icon(str,8,voltages[6]); - gfx_poke_str(0,2,str); - - sprintf(str,"[] %.1f [] %.1f %2.2fV",voltages[3],voltages[7],bat_volts); - insert_bat_icon(str,0,voltages[3]); - insert_bat_icon(str,8,voltages[7]); - gfx_poke_str(0,3,str); - gfx_flush(); -} - -int low_battery_alert = 0; - -void remote_check_for_low_battery(void) { - char bat_gauge[5] = {0,0,0,0,0}; - - low_battery_alert = 0; - empty_serial(); - - Serial_SendByte('c'); - Serial_SendByte('\r'); - Delay_MS(1); - int ok = remote_receive_string(0); - if (!ok) return; - - for (int i=0; i<8; i++) { - // TODO: only accept digits - voltages[i] = ((float)((response[i*3]-'0')*10 + (response[i*3+1]-'0')))/10.0; - if (voltages[i]<0) voltages[i]=0; - if (voltages[i]>=10) voltages[i]=9.9; - if (voltages[i]<3.0) { - low_battery_alert = 1; - } - } - - int gauge_offset = 3*8+2+5+2+5+1; - strncpy(bat_gauge, &response[gauge_offset], 3); - - if (bat_gauge[0] == '?') { - // battery charge level unknown - } else { - int percent = atoi(bat_gauge); - if (percent<10) { - low_battery_alert = 1; - } - } - - int syspower_offset = gauge_offset+5; - if (response[syspower_offset] == 'P') { - char digit = response[syspower_offset+1]; - if (digit == '0' || digit == '1') { - int is_computer_on = (digit == '1'); - if (!is_computer_on && remote_som_power_expected_state == 1) { - // LPC says the computer is off, but we didn't expect it to be. - // the only way this happens is if LPC turned off the system - // due to a low battery condition. - // - // The keyboard will then go to sleep accordingly. - - EnterPowerOff(); - reset_keyboard_state(); - } - remote_som_power_expected_state = is_computer_on; - } - } -} - -void remote_get_status(void) { - gfx_clear(); - empty_serial(); - - gfx_poke_str(0, 2, "MNT Reform Keyboard"); - gfx_poke_str(0, 3, KBD_FW_REV); - gfx_on(); - gfx_flush(); - -#ifndef KBD_VARIANT_STANDALONE - int ok = remote_try_command("s", 1); - if (!ok) return; -#endif -} - -int oledbrt=0; -void oled_brightness_inc(void) { - oledbrt+=10; - if (oledbrt>=0xff) oledbrt = 0xff; - gfx_contrast(oledbrt); -} -void oled_brightness_dec(void) { - oledbrt-=10; - if (oledbrt<0) oledbrt = 0; - gfx_contrast(oledbrt); -} - -int16_t pwmval = 8; - -void kbd_brightness_init(void) { - // initial brightness - OCR0A = pwmval; - - // clear/set, WGM1:0 set (Phase correct PWM) - TCCR0A = (1 << 7) | (0 << 6) | (0<<1) | 1; - - // 3=WGM02, (cs02 2:0 -> clock/256 = 100) - TCCR0B = /*(1 << 3) |*/ (1 << 0) | (0 << 1) | 1; -} - -void kbd_brightness_inc(void) { - pwmval+=2; - if (pwmval>=10) pwmval = 10; - OCR0A = pwmval; -} - -void kbd_brightness_dec(void) { - pwmval-=2; - if (pwmval<0) pwmval = 0; - OCR0A = pwmval; -} - -void kbd_brightness_set(int brite) { - pwmval = brite; - if (pwmval<0) pwmval = 0; - if (pwmval>=10) pwmval = 10; - OCR0A = pwmval; -} - -void remote_turn_on_som(void) { - gfx_clear(); - - int ok = remote_try_command("1p", 0); - if (!ok) return; - - anim_hello(); - kbd_brightness_init(); - - remote_som_power_expected_state = 1; -} - -void remote_turn_off_som(void) { - anim_goodbye(); - - int ok = remote_try_command("0p", 0); - if (!ok) return; - - remote_som_power_expected_state = 0; -} - -void remote_reset_som(void) { - int ok = remote_try_command("2p", 0); - if (!ok) return; -} - -void remote_wake_som(void) { - int ok = remote_try_command("1w", 0); - if (!ok) return; - ok = remote_try_command("0w", 0); - if (!ok) return; -} - -void remote_turn_off_aux(void) { - int ok = remote_try_command("3p", 0); - if (!ok) return; -} - -void remote_turn_on_aux(void) { - int ok = remote_try_command("4p", 0); - if (!ok) return; -} - -void remote_report_voltages(void) { - int ok = remote_try_command("0c", 0); - if (!ok) return; -} - -void remote_enable_som_uart(void) { - int ok = remote_try_command("1u", 0); - if (!ok) return; -} - -void remote_disable_som_uart(void) { - int ok = remote_try_command("0u", 0); - if (!ok) return; -} - -typedef struct MenuItem { - char* title; - int keycode; -} MenuItem; - -#ifdef KBD_VARIANT_STANDALONE -#define MENU_NUM_ITEMS 4 -const MenuItem menu_items[] = { - { "Exit Menu ESC", KEY_ESCAPE }, - { "Key Backlight- F1", KEY_F1 }, - { "Key Backlight+ F2", KEY_F2 }, - { "System Status s", KEY_S } -}; -#else -#define MENU_NUM_ITEMS 9 -const MenuItem menu_items[] = { - { "Exit Menu ESC", KEY_ESCAPE }, - { "Power On 1", KEY_1 }, - { "Power Off 0", KEY_0 }, - { "Reset r", KEY_R }, - { "Battery Status b", KEY_B }, - { "Key Backlight- F1", KEY_F1 }, - { "Key Backlight+ F2", KEY_F2 }, - { "Wake SPC", KEY_SPACE }, - { "System Status s", KEY_S }, - - // Only needed for debugging. - // The keyboard will go to sleep when turning off - // main system power. - { "KBD Power-Off p", KEY_P }, -}; -#endif - -int current_menu_y = 0; -int current_scroll_y = 0; -int active_meta_mode = 0; - -int execute_meta_function(int keycode); - -void render_menu(int y) { - gfx_clear(); - gfx_invert_row(current_menu_y-y); - for (int i=0; i<MENU_NUM_ITEMS; i++) { - gfx_poke_str(0,i-y,menu_items[i].title); - } - gfx_on(); - gfx_flush(); -} - -int execute_menu_function(int y) { - if (y>=0 && y<MENU_NUM_ITEMS) { - return execute_meta_function(menu_items[y].keycode); - } - return execute_meta_function(KEY_ESCAPE); -} - -// returns 1 for navigation function (stay in meta mode), 0 for terminal function -int execute_meta_function(int keycode) { - if (keycode == KEY_0) { - // TODO: are you sure? - remote_turn_off_som(); - EnterPowerOff(); - // Directly enter menu again - return 2; - } - else if (keycode == KEY_1) { - remote_turn_on_som(); - return 0; - } - else if (keycode == KEY_R) { - // TODO: are you sure? - remote_reset_som(); - } - else if (keycode == KEY_SPACE) { - remote_wake_som(); - } - /*else if (keycode == KEY_V) { - remote_turn_off_aux(); - }*/ - else if (keycode == KEY_B) { - remote_get_voltages(); - return 0; - } - else if (keycode == KEY_S) { - remote_get_status(); - return 0; - } - else if (keycode == KEY_F1) { - kbd_brightness_dec(); - return 1; - } - else if (keycode == KEY_F2) { - kbd_brightness_inc(); - return 1; - } - else if (keycode == HID_KEYBOARD_SC_UP_ARROW) { - current_menu_y--; - if (current_menu_y<0) current_menu_y = 0; - if (current_menu_y<=current_scroll_y) current_scroll_y--; - if (current_scroll_y<0) current_scroll_y = 0; - render_menu(current_scroll_y); - return 1; - } - else if (keycode == HID_KEYBOARD_SC_DOWN_ARROW) { - current_menu_y++; - if (current_menu_y>=MENU_NUM_ITEMS) current_menu_y = MENU_NUM_ITEMS-1; - if (current_menu_y>=current_scroll_y+3) current_scroll_y++; - render_menu(current_scroll_y); - return 1; - } - else if (keycode == KEY_ENTER) { - return execute_menu_function(current_menu_y); - } - else if (keycode == KEY_ESCAPE) { - gfx_clear(); - gfx_flush(); - } - else if (keycode == KEY_P) { - EnterPowerOff(); - // Directly enter menu again - return 2; - } - - gfx_clear(); - gfx_flush(); - - return 0; -} - -uint8_t last_meta_key = 0; - -// enter the menu -void enter_meta_mode(void) { - current_scroll_y = 0; - current_menu_y = 0; - active_meta_mode = 1; - // render menu - render_menu(current_scroll_y); -} - -void reset_keyboard_state(void) { - for (int i=0; i<COLS*ROWS; i++) { - matrix_debounce[i] = 0; - matrix_state[i] = 0; - } - last_meta_key = 0; -} - -void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardReport) { - // how many keys are pressed this round - uint8_t total_pressed = 0; - uint8_t used_key_codes = 0; - - // pull ROWs low one after the other - for (int y=0; y<ROWS; y++) { - switch (y) { - case 0: output_low(PORTB, 6); break; - case 1: output_low(PORTB, 5); break; - case 2: output_low(PORTB, 4); break; - case 3: output_low(PORTD, 7); break; - case 4: output_low(PORTD, 6); break; - case 5: output_low(PORTD, 4); break; - } - - // wait for signal to stabilize - // TODO maybe not necessary - _delay_us(10); - - // check input COLs - for (int x=0; x<14; x++) { - uint16_t loc = y*COLS+x; - uint16_t keycode = matrix[loc]; - uint8_t pressed = 0; - uint8_t debounced_pressed = 0; - - // column pins are all over the place - switch (x) { - case 0: pressed = !(PIND&(1<<5)); break; - case 1: pressed = !(PINF&(1<<7)); break; - case 2: pressed = !(PINE&(1<<6)); break; - case 3: pressed = !(PINC&(1<<7)); break; - case 4: pressed = !(PINB&(1<<3)); break; - case 5: pressed = !(PINB&(1<<2)); break; - case 6: pressed = !(PINB&(1<<1)); break; - case 7: pressed = !(PINB&(1<<0)); break; - case 8: pressed = !(PINF&(1<<0)); break; - case 9: pressed = !(PINF&(1<<1)); break; - case 10: pressed = !(PINF&(1<<4)); break; - case 11: pressed = !(PINF&(1<<5)); break; - case 12: pressed = !(PINF&(1<<6)); break; - case 13: pressed = !(PINC&(1<<6)); break; - } - - // shift new state as bit into debounce "register" - matrix_debounce[loc] = (matrix_debounce[loc]<<1)|pressed; - - // if unclear state, we need to keep the last state of the key - if (matrix_debounce[loc] == 0x00) { - matrix_state[loc] = 0; - } else if (matrix_debounce[loc] == 0x01) { - matrix_state[loc] = 1; - } - debounced_pressed = matrix_state[loc]; - - if (debounced_pressed) { - total_pressed++; - - // circle key? - if (keycode == HID_KEYBOARD_SC_EXSEL) { - if (!active_meta_mode && !last_meta_key) { - enter_meta_mode(); - } - } else { - if (active_meta_mode) { - // not holding the same key? - if (last_meta_key != keycode) { - // hyper/circle/menu functions - int stay_meta = execute_meta_function(keycode); - // don't repeat action while key is held down - last_meta_key = keycode; - - // exit meta mode - if (!stay_meta) { - active_meta_mode = 0; - } - - // after wake-up from sleep mode, skip further keymap processing - if (stay_meta == 2) { - reset_keyboard_state(); - enter_meta_mode(); - return; - } - } - } else if (!last_meta_key) { - // not meta mode, regular key: report keypress via USB - // 6 keys is a hard limit in the HID descriptor :/ - if (usb_report_mode && KeyboardReport && used_key_codes<6) { - KeyboardReport->KeyCode[used_key_codes++] = keycode; - } - } - } - } - } - - switch (y) { - case 0: output_high(PORTB, 6); break; - case 1: output_high(PORTB, 5); break; - case 2: output_high(PORTB, 4); break; - case 3: output_high(PORTD, 7); break; - case 4: output_high(PORTD, 6); break; - case 5: output_high(PORTD, 4); break; - } - } - - // if no more keys are held down, allow a new meta command - if (total_pressed<1) last_meta_key = 0; -} - -int blink = 0; - -void process_alerts(void) { - if (low_battery_alert) { - gfx_on(); - for (int x=8;x<=11;x++) { - gfx_poke( x,0,' '); - } - if (blink) { - gfx_poke( 9,0,4*32+2); - gfx_poke(10,0,4*32+3); - } - gfx_flush(); - } - blink = 1-blink; -} - -int main(void) -{ -#ifdef KBD_VARIANT_QWERTY_US - matrix[COLS*4+1]=KEY_DELETE; -#endif -#ifdef KBD_VARIANT_NEO2 - matrix[COLS*3+0]=HID_KEYBOARD_SC_CAPS_LOCK; // M3 - matrix[COLS*2+13]=KEY_ENTER; - matrix[COLS*3+13]=KEY_BACKSLASH_AND_PIPE; // M3 -#endif - - SetupHardware(); - GlobalInterruptEnable(); - anim_hello(); - - int counter = 0; - - for (;;) - { - process_keyboard(0, NULL); - HID_Device_USBTask(&Keyboard_HID_Interface); - USB_USBTask(); - counter++; -#ifndef KBD_VARIANT_STANDALONE - if (counter>=100000) { - remote_check_for_low_battery(); - counter = 0; - } - if (counter%750 == 0) { - process_alerts(); - } -#endif - } -} - -void SetupHardware(void) -{ - // Disable watchdog if enabled by bootloader/fuses - MCUSR &= ~(1 << WDRF); - wdt_disable(); - - // Disable clock division - clock_prescale_set(clock_div_1); - - // declare port pins as inputs (0) and outputs (1) - DDRB = 0b11110000; - DDRC = 0b00000000; - DDRD = 0b11011001; - DDRE = 0b00000000; - DDRF = 0b00000000; - - // initial pin states - PORTB = 0b10001111; - PORTC = 0b11000000; - PORTD = 0b00100000; - PORTE = 0b01000000; - PORTF = 0b11111111; - - // disable JTAG - MCUCR |=(1<<JTD); - MCUCR |=(1<<JTD); - - kbd_brightness_init(); - gfx_init(false); - - Serial_Init(57600, false); - USB_Init(); -} - -/* Setup the AVR to enter the Power-Down state to greatly save power. - * Configures all outputs to be in the low state if possible, and disables - * services like USB and Serial. - * - * Will leave the ports setup so that the Circle key row is being scanned - * so when the watchdog wakes up it can quickly check and go back to sleep if not - * Added by Chartreuse - 2021/08/14 - * - */ -void EnterPowerOff(void) -{ - USB_Disable(); // Stop USB stack so it doesn't wake us up - - // turn off backlight, but don't overwrite setting - OCR0A = 0; - - // Turn off OLED to save power - gfx_clear_screen(); - gfx_off(); - // Disable ADC to save even more power - ADCSRA=0; - - cli(); // No interrupts - - // Set all ports not floating if possible, leaving pullups alone - PORTB=0x3F; // Leave pull-up on all the columns on PB0-3, drive rows 2-3 high, 1-low - PORTC=0xC0; - PORTD=0xF0; // Keep pullup on PD5 like setup did, drive rows 4,5,6 high - PORTE=0x40; // Pullup on PE6 - PORTF=0xFF; // Pullups on PF (columns) - // ROW1 is the only row driven low and left low, thus is always ready to be read out - // We just need to check COL14 (PC6) if it is low (pressed) or high - - // Unfortunately the circle key is on COL14(PC6) which doesn't have pin change interrupt - // capabilities, so we need to wake up every so often to check if it is pressed, and - // if so bring us out of power-off - // We can use the Watchdog timer to do this. - - do { - wdt_reset(); - WDTCSR = (1<<WDCE) | (1<<WDE); // Enable writes to watchdog - WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (0<<WDP0); // Interrupt mode, 1s timeout - - // Enter Power-save mode - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - sleep_enable(); - sei(); // Enable interrupts so we can actually wake - sleep_cpu(); // Actually go to sleep - // Zzzzzz - sleep_disable(); // We've woken up - sei(); - // Check if circle key has been pressed (active-low) - // If not reset the watchdog and try again - } while(PINC&(1<<6)); - - // Resume and reinitialize hardware - SetupHardware(); -} - -ISR(WDT_vect) -{ - // WDT interrupt enable and flag cleared on entry - wdt_disable(); // Disable watchdog for now -} - - -/** Event handler for the library USB Connection event. */ -void EVENT_USB_Device_Connect(void) -{ -} - -/** Event handler for the library USB Disconnection event. */ -void EVENT_USB_Device_Disconnect(void) -{ -} - -/** Event handler for the library USB Configuration Changed event. */ -void EVENT_USB_Device_ConfigurationChanged(void) -{ - bool ConfigSuccess = true; - - ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface); - - USB_Device_EnableSOFEvents(); -} - -/** Event handler for the library USB Control Request reception event. */ -void EVENT_USB_Device_ControlRequest(void) -{ - HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); -} - -/** Event handler for the USB device Start Of Frame event. */ -void EVENT_USB_Device_StartOfFrame(void) -{ - HID_Device_MillisecondElapsed(&Keyboard_HID_Interface); -} - -/** HID class driver callback function for the creation of HID reports to the host. - * - * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced - * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID - * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature - * \param[out] ReportData Pointer to a buffer where the created report should be stored - * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) - * - * \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent - */ - -bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, - uint8_t* const ReportID, - const uint8_t ReportType, - void* ReportData, - uint16_t* const ReportSize) -{ - USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; - - process_keyboard(1, KeyboardReport); - - *ReportSize = sizeof(USB_KeyboardReport_Data_t); - return false; -} - -/** HID class driver callback function for the processing of HID reports from the host. - * - * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced - * \param[in] ReportID Report ID of the received report from the host - * \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature - * \param[in] ReportData Pointer to a buffer where the received report has been stored - * \param[in] ReportSize Size in bytes of the received HID report - */ -void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, - const uint8_t ReportID, - const uint8_t ReportType, - const void* ReportData, - const uint16_t ReportSize) -{ - uint8_t* data = (uint8_t*)ReportData; - if (ReportSize<4) return; - - if (data[0]=='O' && data[1]=='L' && data[2]=='E' && data[3]=='D') { - // OLED: write characters on display - gfx_on(); - for (int y=0; y<4; y++) { - for (int x=0; x<21; x++) { - gfx_poke(x,y,data[4+y*21+x]); - } - } - gfx_flush(); - } - if (data[0]=='O' && data[1]=='I' && data[2]=='N' && data[3]=='V') { - gfx_clear_invert(); - gfx_invert_row(data[4]-'0'); - } - else if (data[0]=='L' && data[1]=='I' && data[2]=='T' && data[3]=='E') { - char brite = data[4]-'0'; - brite++; - if (brite<=1) brite=0; - if (brite>9) brite=9; - kbd_brightness_set(brite); - } - else if (data[0]=='P' && data[1]=='W' && data[2]=='R' && data[3]=='0') { - // PWR0: shutdown (turn off power rails) - remote_turn_off_som(); - EnterPowerOff(); - reset_keyboard_state(); - } - else if (data[0]=='P' && data[1]=='W' && data[2]=='R' && data[3]=='3') { - // PWR3: aux power off - remote_turn_off_aux(); - } - else if (data[0]=='P' && data[1]=='W' && data[2]=='R' && data[3]=='4') { - // PWR4: aux power on - remote_turn_on_aux(); - } - else if (data[0]=='U' && data[1]=='A' && data[2]=='R' && data[3]=='1') { - // UAR1: UART reporting on - remote_enable_som_uart(); - } - else if (data[0]=='U' && data[1]=='A' && data[2]=='R' && data[3]=='0') { - // UAR0: UART reporting off - remote_disable_som_uart(); - } - else if (data[0]=='R' && data[1]=='P' && data[2]=='R' && data[3]=='T') { - // RPRT: Report power stats to UART - remote_report_voltages(); - } -} diff --git a/reform2-keyboard-fw/Keyboard.h b/reform2-keyboard-fw/Keyboard.h @@ -1,91 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2018. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaims all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * - * Header file for Keyboard.c. - */ - -#ifndef _KEYBOARD_H_ -#define _KEYBOARD_H_ - - /* Includes: */ - #include <avr/io.h> - #include <avr/wdt.h> - #include <avr/power.h> - #include <avr/interrupt.h> - #include <stdbool.h> - #include <string.h> - - #include "Descriptors.h" - - #include <LUFA/Drivers/Board/Joystick.h> - #include <LUFA/Drivers/Board/LEDs.h> - #include <LUFA/Drivers/Board/Buttons.h> - #include <LUFA/Drivers/USB/USB.h> - #include <LUFA/Platform/Platform.h> - - /* Macros: */ - /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ - #define LEDMASK_USB_NOTREADY LEDS_LED1 - - /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ - #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) - - /** LED mask for the library LED driver, to indicate that the USB interface is ready. */ - #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) - - /** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */ - #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3) - - /* Function Prototypes: */ - void SetupHardware(void); - void EnterPowerOff(void); - void reset_keyboard_state(void); - - void EVENT_USB_Device_Connect(void); - void EVENT_USB_Device_Disconnect(void); - void EVENT_USB_Device_ConfigurationChanged(void); - void EVENT_USB_Device_ControlRequest(void); - void EVENT_USB_Device_StartOfFrame(void); - - bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, - uint8_t* const ReportID, - const uint8_t ReportType, - void* ReportData, - uint16_t* const ReportSize); - void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, - const uint8_t ReportID, - const uint8_t ReportType, - const void* ReportData, - const uint16_t ReportSize); - -#endif - diff --git a/reform2-keyboard-fw/Makefile b/reform2-keyboard-fw/Makefile @@ -17,8 +17,8 @@ BOARD = USBKEY F_CPU = 16000000 F_USB = $(F_CPU) OPTIMIZATION = s -TARGET = Keyboard -SRC = $(TARGET).c Descriptors.c i2c.c ssd1306.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) +TARGET = keyboard +SRC = $(TARGET).c descriptors.c i2c.c oled.c remote.c powersave.c backlight.c menu.c hid_report.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) LUFA_PATH = ./lufa-master/LUFA CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER $(REFORM_KBD_OPTIONS) -IConfig/ LD_FLAGS = -Wl,-u,vfprintf -lprintf_flt diff --git a/reform2-keyboard-fw/README.md b/reform2-keyboard-fw/README.md @@ -0,0 +1,49 @@ +# MNT Reform 2.0 Keyboard Firmware + +## Code Structure + +- `constants.h`: Define which keyboard variant you want to build for +- `keyboard.c`: Main entrypoint that includes the chosen matrix file (keyboard layout) +- `matrix.h`: Keyboard layout definition (default) +- `matrix_*.h`: Alternative layouts +- `backlight.c`: Keyboard backlight control +- `menu.c`: OLED Menu handling +- `oled.c`: OLED graphics control +- `remote.c`: Communication with MNT Reform motherboard LPC +- `hid_report.c`: USB HID raw report handler (commands sent by OS) +- `powersave.c`: Low power/sleep mode +- `descriptors.c`: USB HID descriptors +- `i2c.c`: Soft I2C master implementation (for OLED) +- `serial.c`: Soft UART implementation +- `font.c`: Bitmap data for OLED font and icons + +## Dependencies + +### Debian/Ubuntu + +`apt install gcc-avr avr-libc dfu-programmer` + +### Mac + +*TODO: is this correct?* + +``` +brew tap osx-cross/avr +brew install avr-gcc +brew install dfu-programmer +``` + +## Hacking + +To change the keyboard layout, adjust the `matrix` arrays in `keyboard.c`. + +## Building + +*Important*: Adjust the variant settings in `constants.h` do match your keyboard or laptop model. +I.e., if you are targeting the Standalone Keyboard, uncomment the `#define KBD_VARIANT_STANDALONE`. + +To build, type: +`make` + +To flash, put your keyboard into [flashing mode](https://mntre.com/reform2/handbook/parts.html#keyboard-firmware) and run: +`sudo ./flash.sh` diff --git a/reform2-keyboard-fw/backlight.c b/reform2-keyboard-fw/backlight.c @@ -0,0 +1,41 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#include <avr/io.h> +#include <stdint.h> +#include "backlight.h" + +int16_t pwmval = 8; + +void kbd_brightness_init(void) { + // initial brightness + OCR0A = pwmval; + + // clear/set, WGM1:0 set (Phase correct PWM) + TCCR0A = (1 << 7) | (0 << 6) | (0<<1) | 1; + + // 3=WGM02, (cs02 2:0 -> clock/256 = 100) + TCCR0B = /*(1 << 3) |*/ (1 << 0) | (0 << 1) | 1; +} + +void kbd_brightness_inc(void) { + pwmval+=2; + if (pwmval>=10) pwmval = 10; + OCR0A = pwmval; +} + +void kbd_brightness_dec(void) { + pwmval-=2; + if (pwmval<0) pwmval = 0; + OCR0A = pwmval; +} + +void kbd_brightness_set(int brite) { + pwmval = brite; + if (pwmval<0) pwmval = 0; + if (pwmval>=10) pwmval = 10; + OCR0A = pwmval; +} diff --git a/reform2-keyboard-fw/backlight.h b/reform2-keyboard-fw/backlight.h @@ -0,0 +1,15 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _BACKLIGHT_H_ +#define _BACKLIGHT_H_ + +void kbd_brightness_init(void); +void kbd_brightness_inc(void); +void kbd_brightness_dec(void); +void kbd_brightness_set(int brite); + +#endif diff --git a/reform2-keyboard-fw/constants.h b/reform2-keyboard-fw/constants.h @@ -0,0 +1,21 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _CONSTANTS_H_ +#define _CONSTANTS_H_ + +#define KBD_FW_REV "R1 20220221" +#define KBD_VARIANT_QWERTY_US +//#define KBD_VARIANT_STANDALONE +//#define KBD_VARIANT_NEO2 +//#define KBD_VARIANT_V + +#define KBD_COLS 14 +#define KBD_ROWS 6 +#define KBD_MATRIX_SZ KBD_COLS * KBD_ROWS + 4 +#define KBD_EDITOR_MARKER 0xfe,0xed,0xca,0xfe + +#endif diff --git a/reform2-keyboard-fw/descriptors.c b/reform2-keyboard-fw/descriptors.c @@ -0,0 +1,279 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +/** \file + * + * USB Device Descriptors, for library use when in USB device mode. Descriptors are special + * computer-readable structures which the host requests upon device enumeration, to determine + * the device's capabilities and functions. + */ + +#include "Config/LUFAConfig.h" +#include "descriptors.h" + + +/** HID class report descriptor. This is a special descriptor constructed with values from the + * USBIF HID class specification to describe the reports and capabilities of the HID device. This + * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) + * the device will send, and what it may be sent back from the host. Refer to the HID specification for + * more details on HID report descriptors. + */ +const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = +{ + /* Use the HID class driver's standard Keyboard report. + * Max simultaneous keys: 6 + */ + HID_DESCRIPTOR_KEYBOARD(6) +}; + +/** HID class report descriptor. This is a special descriptor constructed with values from the + * USBIF HID class specification to describe the reports and capabilities of the HID device. This + * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) + * the device will send, and what it may be sent back from the host. Refer to the HID specification for + * more details on HID report descriptors. + */ +const USB_Descriptor_HIDReport_Datatype_t PROGMEM MediaControlReport[] = +{ + HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer Page */ + HID_RI_USAGE(8, 0x01), /* Consumer Controls */ + HID_RI_COLLECTION(8, 0x01), /* Application */ + HID_RI_USAGE(8, 0xB0), /* Play */ + HID_RI_USAGE(8, 0xB1), /* Pause */ + HID_RI_USAGE(8, 0xB3), /* Fast Forward */ + HID_RI_USAGE(8, 0xB4), /* Rewind */ + HID_RI_USAGE(8, 0xB5), /* Next Track */ + HID_RI_USAGE(8, 0xB6), /* Previous Track */ + HID_RI_USAGE(8, 0xB7), /* Stop */ + HID_RI_USAGE(8, 0xCD), /* Play/Pause (toggle) */ + HID_RI_USAGE(8, 0xE2), /* Mute */ + HID_RI_USAGE(8, 0xE9), /* Volume Up */ + HID_RI_USAGE(8, 0xEA), /* Volume Down */ + HID_RI_REPORT_SIZE(8, 0x01), + HID_RI_REPORT_COUNT(8, 0x0B), + HID_RI_LOGICAL_MINIMUM(8, 0), + HID_RI_LOGICAL_MAXIMUM(8, 1), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), + HID_RI_REPORT_COUNT(8, 0x05), + HID_RI_INPUT(8, HID_IOF_CONSTANT), + HID_RI_END_COLLECTION(0), +}; + +/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall + * device characteristics, including the supported USB version, control endpoint size and the + * number of device configurations. The descriptor is read out by the USB host when the enumeration + * process begins. + */ +const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = +{ + .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, + + .USBSpecification = VERSION_BCD(1,1,0), + .Class = USB_CSCP_NoDeviceClass, + .SubClass = USB_CSCP_NoDeviceSubclass, + .Protocol = USB_CSCP_NoDeviceProtocol, + + .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, + + .VendorID = 0x03EB, + .ProductID = 0x2042, + .ReleaseNumber = VERSION_BCD(0,0,1), + + .ManufacturerStrIndex = STRING_ID_Manufacturer, + .ProductStrIndex = STRING_ID_Product, + .SerialNumStrIndex = NO_DESCRIPTOR, + + .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS +}; + +/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage + * of the device in one of its supported configurations, including information about any device interfaces + * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting + * a configuration so that the host may correctly communicate with the USB device. + */ +const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = +{ + .Config = + { + .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, + + .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), + .TotalInterfaces = 2, + + .ConfigurationNumber = 1, + .ConfigurationStrIndex = NO_DESCRIPTOR, + + .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED), + + .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + }, + + .HID1_KeyboardInterface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = INTERFACE_ID_Keyboard, + .AlternateSetting = 0x00, + + .TotalEndpoints = 1, + + .Class = HID_CSCP_HIDClass, + .SubClass = HID_CSCP_BootSubclass, + .Protocol = HID_CSCP_KeyboardBootProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .HID1_KeyboardHID = + { + .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, + + .HIDSpec = VERSION_BCD(1,1,1), + .CountryCode = 0x00, + .TotalReportDescriptors = 1, + .HIDReportType = HID_DTYPE_Report, + .HIDReportLength = sizeof(KeyboardReport) + }, + + .HID1_ReportINEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = KEYBOARD_EPADDR, + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = HID_EPSIZE, + .PollingIntervalMS = 10 + }, + + .HID2_MediaControlInterface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = INTERFACE_ID_MediaControl, + .AlternateSetting = 0x00, + + .TotalEndpoints = 1, + + .Class = HID_CSCP_HIDClass, + .SubClass = HID_CSCP_NonBootSubclass, + .Protocol = HID_CSCP_NonBootProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .HID2_MediaControlHID = + { + .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, + + .HIDSpec = VERSION_BCD(1,1,1), + .CountryCode = 0x00, + .TotalReportDescriptors = 1, + .HIDReportType = HID_DTYPE_Report, + .HIDReportLength = sizeof(MediaControlReport) + }, + + .HID2_ReportINEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = MEDIACONTROL_EPADDR, + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = HID_EPSIZE, + .PollingIntervalMS = 100 + }, +}; + +/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests + * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate + * via the language ID table available at USB.org what languages the device supports for its string descriptors. + */ +const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG); + +/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable + * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(L"MNT"); + +/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, + * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Reform Keyboard"); + +/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" + * documentation) by the application code so that the address and size of a requested descriptor can be given + * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function + * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the + * USB host. + */ +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint16_t wIndex, + const void** const DescriptorAddress) +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorNumber) + { + case STRING_ID_Language: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case STRING_ID_Manufacturer: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case STRING_ID_Product: + Address = &ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + break; + } + break; + case HID_DTYPE_HID: + switch (wIndex) + { + case INTERFACE_ID_Keyboard: + Address = &ConfigurationDescriptor.HID1_KeyboardHID; + Size = sizeof(USB_HID_Descriptor_HID_t); + break; + case INTERFACE_ID_MediaControl: + Address = &ConfigurationDescriptor.HID2_MediaControlHID; + Size = sizeof(USB_HID_Descriptor_HID_t); + break; + } + break; + case HID_DTYPE_Report: + switch (wIndex) + { + case INTERFACE_ID_Keyboard: + Address = &KeyboardReport; + Size = sizeof(KeyboardReport); + break; + case INTERFACE_ID_MediaControl: + Address = &MediaControlReport; + Size = sizeof(MediaControlReport); + break; + } + break; + } + + *DescriptorAddress = Address; + return Size; +} diff --git a/reform2-keyboard-fw/descriptors.h b/reform2-keyboard-fw/descriptors.h @@ -0,0 +1,76 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +/** \file + * + * Header file for Descriptors.c. + */ + +#ifndef _DESCRIPTORS_H_ +#define _DESCRIPTORS_H_ + + /* Includes: */ + #include <avr/pgmspace.h> + + #include <LUFA/Drivers/USB/USB.h> + + /* Type Defines: */ + /** Type define for the device configuration descriptor structure. This must be defined in the + * application code, as the configuration descriptor contains several sub-descriptors which + * vary between devices, and which describe the device's usage to the host. + */ + typedef struct + { + USB_Descriptor_Configuration_Header_t Config; + + // Keyboard HID Interface + USB_Descriptor_Interface_t HID1_KeyboardInterface; + USB_HID_Descriptor_HID_t HID1_KeyboardHID; + USB_Descriptor_Endpoint_t HID1_ReportINEndpoint; + // Media Control HID Interface + USB_Descriptor_Interface_t HID2_MediaControlInterface; + USB_HID_Descriptor_HID_t HID2_MediaControlHID; + USB_Descriptor_Endpoint_t HID2_ReportINEndpoint; + } USB_Descriptor_Configuration_t; + + /** Enum for the device interface descriptor IDs within the device. Each interface descriptor + * should have a unique ID index associated with it, which can be used to refer to the + * interface from other descriptors. + */ + enum InterfaceDescriptors_t + { + INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */ + INTERFACE_ID_MediaControl = 1, /**< Media Control interface descriptor ID */ + }; + + /** Enum for the device string descriptor IDs within the device. Each string descriptor should + * have a unique ID index associated with it, which can be used to refer to the string from + * other descriptors. + */ + enum StringDescriptors_t + { + STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ + STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ + STRING_ID_Product = 2, /**< Product string ID */ + }; + + /* Macros: */ + /** Endpoint address of the Keyboard HID reporting IN endpoint. */ + #define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1) + + /** Endpoint address of the Media Control HID reporting IN endpoint. */ + #define MEDIACONTROL_EPADDR (ENDPOINT_DIR_IN | 3) + + /** Size in bytes of HID reporting IN endpoints. */ + #define HID_EPSIZE 8 + + /* Function Prototypes: */ +//uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, +// const uint16_t wIndex, +// const void** const DescriptorAddress) +// ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); + +#endif diff --git a/reform2-keyboard-fw/flash.sh b/reform2-keyboard-fw/flash.sh @@ -2,6 +2,6 @@ dfu-programmer atmega32u4 erase --suppress-bootloader-mem -dfu-programmer atmega32u4 flash ./Keyboard.hex --suppress-bootloader-mem +dfu-programmer atmega32u4 flash ./keyboard.hex --suppress-bootloader-mem dfu-programmer atmega32u4 start diff --git a/reform2-keyboard-fw/font.c b/reform2-keyboard-fw/font.c @@ -1,3 +1,9 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + #include <avr/pgmspace.h> const unsigned char font[] PROGMEM = { diff --git a/reform2-keyboard-fw/hid_report.c b/reform2-keyboard-fw/hid_report.c @@ -0,0 +1,73 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#include <stdint.h> +#include "backlight.h" +#include "hid_report.h" +#include "keyboard.h" +#include "menu.h" +#include "oled.h" +#include "powersave.h" +#include "remote.h" + +// hid commands are all 4-letter, so they fit in a 32 bit integer +#define cmd(_s) (*(uint32_t *)(_s)) +#define CMD_TEXT_FRAME cmd("OLED") // fill the screen with a single wall of text +#define CMD_ROW_INVERT cmd("OINV") // invert a line of text +#define CMD_REPORT_POWER cmd("RPRT") // ask for power stats report over UART +#define CMD_OLED_CLEAR cmd("WCLR") // clear the oled display +#define CMD_OLED_BITMAP cmd("WBIT") // (u16 offset, u8 bytes...) write raw bytes into the oled framebuffer +#define CMD_POWER_OFF cmd("PWR0") // turn off power rails +#define CMD_BACKLIGHT cmd("LITE") // keyboard backlight level +#define CMD_UART_ON cmd("UAR1") // uart reporting on +#define CMD_UART_OFF cmd("UAR0") // uart reporting off + +void hid_report_cmd(uint8_t* data) { + const uint32_t command = *(uint32_t *)data; + + if (command == CMD_TEXT_FRAME) { + gfx_on(); + for (int y=0; y<4; y++) { + for (int x=0; x<21; x++) { + gfx_poke(x,y,data[4+y*21+x]); + } + } + gfx_flush(); + } + else if (command == CMD_ROW_INVERT) { + gfx_clear_invert(); + gfx_invert_row(data[4]-'0'); + } + else if (command == CMD_BACKLIGHT) { + char brite = data[4]-'0'; + brite++; + if (brite<=1) brite=0; + if (brite>9) brite=9; + kbd_brightness_set(brite); + } + else if (command == CMD_POWER_OFF) { + anim_goodbye(); + remote_turn_off_som(); + keyboard_power_off(); + reset_keyboard_state(); + } + else if (command == CMD_UART_ON) { + remote_enable_som_uart(); + } + else if (command == CMD_UART_OFF) { + remote_disable_som_uart(); + } + else if (command == CMD_REPORT_POWER) { + remote_report_voltages(); + } + else if (command == CMD_OLED_BITMAP) { + matrix_render_direct(data+4); + } + else if (command == CMD_OLED_BITMAP) { + gfx_clear(); + gfx_flush(); + } +} diff --git a/reform2-keyboard-fw/hid_report.h b/reform2-keyboard-fw/hid_report.h @@ -0,0 +1,14 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _HID_REPORT_H_ +#define _HID_REPORT_H_ + +#include <stdint.h> + +void hid_report_cmd(uint8_t* data); + +#endif diff --git a/reform2-keyboard-fw/i2c.c b/reform2-keyboard-fw/i2c.c @@ -1,3 +1,9 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + #include <util/twi.h> #include <avr/io.h> #include <stdlib.h> diff --git a/reform2-keyboard-fw/i2c.h b/reform2-keyboard-fw/i2c.h @@ -1,4 +1,11 @@ -#pragma once +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _I2C_H_ +#define _I2C_H_ #include <stdint.h> @@ -36,7 +43,6 @@ static inline unsigned char i2c_start_write(unsigned char addr) { return i2c_master_start((addr << 1) | I2C_WRITE); } -// from SSD1306 scrips extern unsigned char i2c_rep_start(unsigned char addr); extern void i2c_start_wait(unsigned char addr); extern unsigned char i2c_readAck(void); @@ -44,3 +50,5 @@ extern unsigned char i2c_readNak(void); extern unsigned char i2c_read(unsigned char ack); #define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); + +#endif diff --git a/reform2-keyboard-fw/kbdgfx-demo/build.sh b/reform2-keyboard-fw/kbdgfx-demo/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +gcc -O2 -o kbdgfx ./kbdgfx.c -lm + diff --git a/reform2-keyboard-fw/kbdgfx-demo/kbdgfx.c b/reform2-keyboard-fw/kbdgfx-demo/kbdgfx.c @@ -0,0 +1,140 @@ +/* + kbdgfx.c -- Demo for drawing realtime graphics to the MNT Reform Keyboard + Copyright 2022 MNT Research GmbH (https://mntre.com) + License: MIT +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <math.h> +#include <unistd.h> + +#define ROWS 4 +#define COLS 126 +#define BUFSZ (5+COLS*ROWS) +#define FBUFSZ COLS*ROWS*8 + +// our unpacked, wasteful framebuffer (one byte per pixel, 126x32) +uint8_t fb[FBUFSZ]; + +// the buffer we're sending to the keyboard (bit packed and column byte order) +uint8_t buf[BUFSZ]; + +void oled_blit(uint8_t* src, uint8_t* dst) { + for (int y = 0; y < ROWS; y++) { + // right-to-left + for (int x = 0; x < COLS; x++) { + uint8_t column = 0; + + for (int z = 0; z < 8; z++) { + // look up the pixel and threshold it to black and white at 127 + uint8_t bit = src[((y * 8 + 7 - z)*COLS + x)] > 127; + + // bitshift the column byte to the left to make room for new pixel + column <<= 1; + // OR the bit (the pixel) to the column byte + column |= bit; + } + + // store in the destination buffer + dst[y*COLS + x] = column; + } + } +} + +// unused +void fill_pattern(uint8_t bitpattern, uint8_t* dst) { + int i = 0; + for (int y = 0; y < 32; y++) { + for (int x = 0; x < COLS; x++) { + uint8_t pos = x % 8; + uint8_t b = bitpattern & (1<<pos); + + dst[i++] = b ? 1 : 0; + } + } +} + +void draw_sine(float t, uint8_t* dst) { + for (int x=0; x<126; x++) { + int y = 16 + sin(t + ((float)x/126.0 * 3.141))*12; + if (y < 0) y = 0; + if (y > 31) y = 31; + + dst[y*COLS + x] = 0xff; + } +} + +int main(int argc, char** argv) { + // just a counter + uint32_t t = 0; + + if (argc < 2) { + printf("Usage: sudo kbdgfx /dev/hidraw0 [bitmap.raw]\n"); + exit(1); + } + + // loop forever + while (1) { + FILE* f = fopen(argv[1],"w"); + + if (!f) { + printf("Couldn't open %s. Try sudo.\n", argv[1]); + exit(1); + } + + // start with the command + buf[0] = 'x'; + buf[1] = 'W'; + buf[2] = 'B'; + buf[3] = 'I'; + buf[4] = 'T'; + + // clear + memset(fb, 0, FBUFSZ); + + if (argc == 3) { + // read bitmap from file + FILE* bmf = fopen(argv[2],"r"); + if (!bmf) { + printf("Couldn't open bitmap %s!\n", argv[2]); + fclose(f); + exit(2); + } + + int res = fread(fb, FBUFSZ, 1, bmf); + fclose(bmf); + + if (res<1) { + printf("Couldn't read bitmap or wrong size.\n", argv[2]); + fclose(f); + exit(3); + } + } else { + // graphics demo + + // paint + draw_sine((float)t*0.03, fb); + draw_sine((float)t*0.05, fb); + } + + // convert to weird OLED buffer format + oled_blit(fb, buf+5); + + // send our buffer to the keyboard + fwrite(buf, BUFSZ, 1, f); + + fclose(f); + + // if we're in bitmap file mode, exit now + if (argc == 3) exit(0); + + // ~50 FPS + usleep(1000*20); + // ~2 FPS + //usleep(1000*500); + t++; + } +} diff --git a/reform2-keyboard-fw/kbdgfx-demo/picture-floyd.sh b/reform2-keyboard-fw/kbdgfx-demo/picture-floyd.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Usage: ./picture-floyd.sh /dev/hidraw3 picture.jpg + +#convert $2 -resize 126 -crop 126x32+0+0 -depth 8 -dither FloydSteinberg -remap pattern:gray50 gray:temp.bin + +convert $2 -resize 126 -gravity center -extent 126x32 -depth 8 -dither FloydSteinberg -remap pattern:gray50 gray:temp.bin +sudo ./kbdgfx $1 ./temp.bin + diff --git a/reform2-keyboard-fw/kbdgfx-demo/picture.sh b/reform2-keyboard-fw/kbdgfx-demo/picture.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Usage: ./picture.sh /dev/hidraw3 picture.png + +convert $2 -resize 126 -gravity center -extent 126x32 -depth 8 gray:temp.bin +sudo ./kbdgfx $1 ./temp.bin + diff --git a/reform2-keyboard-fw/kbdgfx-demo/text.sh b/reform2-keyboard-fw/kbdgfx-demo/text.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Usage: ./text.sh /dev/hidraw3 18 "hello world" + +convert -size 126x32 -background black -font Inter-Bold.ttf -pointsize $2 -fill white -gravity center caption:"$3" -depth 8 -flatten gray:temp.bin +sudo ./kbdgfx $1 ./temp.bin + diff --git a/reform2-keyboard-fw/keyboard.c b/reform2-keyboard-fw/keyboard.c @@ -0,0 +1,445 @@ +/* + MNT Reform 2.0 Keyboard Firmware + Copyright 2019-2021 Lukas F. Hartmann / MNT Research GmbH, Berlin (lukas@mntre.com) + And Contributors: + Chartreuse + V Körbes + Robey Pointer (robey@lag.net) + + Based on code from LUFA Library (lufa-lib.org): + Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + SPDX-License-Identifier: MIT +*/ + +#include <stdlib.h> +#include <avr/io.h> +#include "backlight.h" +// Important: version and variant info moved here +#include "constants.h" +#include "hid_report.h" +#include "keyboard.h" +#include "menu.h" +#include "oled.h" +#include "powersave.h" +#include "remote.h" +#include "scancodes.h" + +#ifdef KBD_VARIANT_V +#include "matrix_v.h" +#else +#include "matrix.h" +#endif + +/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */ +static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)]; +static uint8_t PrevMediaControlHIDReportBuffer[sizeof(USB_MediaReport_Data_t)]; + +/** LUFA HID Class driver interface configuration and state information. This structure is + * passed to all HID Class driver functions, so that multiple instances of the same class + * within a device can be differentiated from one another. + */ +USB_ClassInfo_HID_Device_t Keyboard_HID_Interface = + { + .Config = + { + .InterfaceNumber = INTERFACE_ID_Keyboard, + .ReportINEndpoint = + { + .Address = KEYBOARD_EPADDR, + .Size = HID_EPSIZE, + .Banks = 1, + }, + .PrevReportINBuffer = PrevKeyboardHIDReportBuffer, + .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer), + }, + }; + +/** LUFA HID Class driver interface configuration and state information for the Media Controller */ +USB_ClassInfo_HID_Device_t MediaControl_HID_Interface = + { + .Config = + { + .InterfaceNumber = INTERFACE_ID_MediaControl, + .ReportINEndpoint = + { + .Address = MEDIACONTROL_EPADDR, + .Size = HID_EPSIZE, + .Banks = 1, + }, + .PrevReportINBuffer = PrevMediaControlHIDReportBuffer, + .PrevReportINBufferSize = sizeof(PrevMediaControlHIDReportBuffer), + }, + }; + +uint8_t matrix_debounce[KBD_COLS*KBD_ROWS]; +uint8_t matrix_state[KBD_COLS*KBD_ROWS]; + +int active_meta_mode = 0; +uint8_t last_meta_key = 0; + +uint8_t* active_matrix = matrix; +bool media_toggle = 0; +bool fn_key = 0; // Am I holding FN? +bool circle = 0; // Am I holding circle? + +// enter the menu +void enter_meta_mode(void) { + active_meta_mode = 1; + reset_and_render_menu(); +} + +void reset_keyboard_state(void) { + for (int i = 0; i < KBD_COLS*KBD_ROWS; i++) { + matrix_debounce[i] = 0; + matrix_state[i] = 0; + } + last_meta_key = 0; +} + +inline bool is_media_key(uint8_t keycode) { + return (keycode>=HID_KEYBOARD_SC_MEDIA_PLAY); +} + +bool get_media_keys(uint8_t keycode, USB_MediaReport_Data_t* mcr) { + bool media_key = false; + if (keycode == HID_KEYBOARD_SC_MEDIA_MUTE) { + if (mcr) mcr->Mute = 1; + media_key = true; + } else if (keycode == HID_KEYBOARD_SC_MEDIA_VOLUME_UP) { + if (mcr) mcr->VolumeUp = 1; + media_key = true; + } else if (keycode == HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN) { + if (mcr) mcr->VolumeDown = 1; + media_key = true; + } else if (keycode == HID_KEYBOARD_SC_MEDIA_BACKWARD) { + if (mcr) mcr->PreviousTrack = 1; + media_key = true; + } else if (keycode == HID_KEYBOARD_SC_MEDIA_FORWARD) { + if (mcr) mcr->NextTrack = 1; + media_key = true; + } else if (keycode == HID_KEYBOARD_SC_MEDIA_PLAY) { + if (mcr) mcr->PlayPause = 1; + media_key = true; + } + return media_key; +} + +#define MAX_SCANCODES 6 +static uint8_t pressed_scancodes[MAX_SCANCODES] = {0,0,0,0,0,0}; + +// usb_report_mode: if you pass 0, you can leave KeyboardReport NULL +int process_keyboard(uint8_t* resulting_scancodes) { + // how many keys are pressed this round + uint8_t total_pressed = 0; + uint8_t used_key_codes = 0; + + // pull ROWs low one after the other + for (int y = 0; y < KBD_ROWS; y++) { + switch (y) { + case 0: output_low(PORTB, 6); break; + case 1: output_low(PORTB, 5); break; + case 2: output_low(PORTB, 4); break; + case 3: output_low(PORTD, 7); break; + case 4: output_low(PORTD, 6); break; + case 5: output_low(PORTD, 4); break; + } + + // wait for signal to stabilize + // TODO maybe not necessary + //_delay_us(10); + + // check input COLs + for (int x=0; x<14; x++) { + uint16_t keycode; + uint16_t loc = y*KBD_COLS+x; + keycode = active_matrix[loc]; + uint8_t pressed = 0; + uint8_t debounced_pressed = 0; + + // column pins are all over the place + switch (x) { + case 0: pressed = !(PIND&(1<<5)); break; + case 1: pressed = !(PINF&(1<<7)); break; + case 2: pressed = !(PINE&(1<<6)); break; + case 3: pressed = !(PINC&(1<<7)); break; + case 4: pressed = !(PINB&(1<<3)); break; + case 5: pressed = !(PINB&(1<<2)); break; + case 6: pressed = !(PINB&(1<<1)); break; + case 7: pressed = !(PINB&(1<<0)); break; + case 8: pressed = !(PINF&(1<<0)); break; + case 9: pressed = !(PINF&(1<<1)); break; + case 10: pressed = !(PINF&(1<<4)); break; + case 11: pressed = !(PINF&(1<<5)); break; + case 12: pressed = !(PINF&(1<<6)); break; + case 13: pressed = !(PINC&(1<<6)); break; + } + + // shift new state as bit into debounce "register" + matrix_debounce[loc] = (matrix_debounce[loc]<<1)|pressed; + + // if unclear state, we need to keep the last state of the key + if (matrix_debounce[loc] == 0x00) { + matrix_state[loc] = 0; + } else if (matrix_debounce[loc] == 0x01) { + matrix_state[loc] = 1; + } + debounced_pressed = matrix_state[loc]; + + if (debounced_pressed) { + total_pressed++; + + // Is circle key pressed? + if (keycode == KEY_CIRCLE) { + if (fn_key) { + circle = 1; + } else { + if (!active_meta_mode && !last_meta_key) { + enter_meta_mode(); + } + } + } else if (keycode == HID_KEYBOARD_SC_EXECUTE) { + fn_key = 1; + active_matrix = matrix_fn; + } else { + if (active_meta_mode) { + // not holding the same key? + if (last_meta_key != keycode) { + // hyper/circle/menu functions + int stay_meta = execute_meta_function(keycode); + // don't repeat action while key is held down + last_meta_key = keycode; + + // exit meta mode + if (!stay_meta) { + active_meta_mode = 0; + } + + // after wake-up from sleep mode, skip further keymap processing + if (stay_meta == 2) { + reset_keyboard_state(); + enter_meta_mode(); + return 0; + } + } + } else if (!last_meta_key) { + // not meta mode, regular key: report keypress via USB + // 6 keys is the limit in the HID descriptor + if (used_key_codes < MAX_SCANCODES && resulting_scancodes) { + resulting_scancodes[used_key_codes++] = keycode; + } + } + } + } else { + // key not pressed + if (keycode == HID_KEYBOARD_SC_EXECUTE) { + fn_key = 0; + if (media_toggle) { + active_matrix = matrix_fn_toggled; + } else { + active_matrix = matrix; + } + } else if (keycode == KEY_CIRCLE) { + if (fn_key && circle) { + if (!media_toggle) { + media_toggle = 1; + active_matrix = matrix_fn_toggled; + } else { + media_toggle = 0; + active_matrix = matrix_fn; + } + } + circle = 0; + } + } + } + + switch (y) { + case 0: output_high(PORTB, 6); break; + case 1: output_high(PORTB, 5); break; + case 2: output_high(PORTB, 4); break; + case 3: output_high(PORTD, 7); break; + case 4: output_high(PORTD, 6); break; + case 5: output_high(PORTD, 4); break; + } + } + + // if no more keys are held down, allow a new meta command + if (total_pressed<1) last_meta_key = 0; + + return used_key_codes; +} + +int main(void) +{ +#ifdef KBD_VARIANT_QWERTY_US + matrix[KBD_COLS*4+1]=KEY_DELETE; +#endif +#ifdef KBD_VARIANT_NEO2 + matrix[KBD_COLS*3+0]=HID_KEYBOARD_SC_CAPS_LOCK; // M3 + matrix[KBD_COLS*2+13]=KEY_ENTER; + matrix[KBD_COLS*3+13]=KEY_BACKSLASH_AND_PIPE; // M3 +#endif + + setup_hardware(); + GlobalInterruptEnable(); + anim_hello(); + + int counter = 0; + + for (;;) + { + process_keyboard(NULL); + HID_Device_USBTask(&Keyboard_HID_Interface); + HID_Device_USBTask(&MediaControl_HID_Interface); + USB_USBTask(); + counter++; +#ifndef KBD_VARIANT_STANDALONE + if (counter>=100000) { + remote_check_for_low_battery(); + counter = 0; + } + if (counter%750 == 0) { + remote_process_alerts(); + } +#endif + } +} + +void setup_hardware(void) +{ + // Disable watchdog if enabled by bootloader/fuses + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + // Disable clock division + clock_prescale_set(clock_div_1); + + // declare port pins as inputs (0) and outputs (1) + DDRB = 0b11110000; + DDRC = 0b00000000; + DDRD = 0b11011001; + DDRE = 0b00000000; + DDRF = 0b00000000; + + // initial pin states + PORTB = 0b10001111; + PORTC = 0b11000000; + PORTD = 0b00100000; + PORTE = 0b01000000; + PORTF = 0b11111111; + + // disable JTAG + MCUCR |=(1<<JTD); + MCUCR |=(1<<JTD); + + kbd_brightness_init(); + gfx_init(false); + remote_init(); + USB_Init(); +} + +ISR(WDT_vect) +{ + // WDT interrupt enable and flag cleared on entry + wdt_disable(); // Disable watchdog for now +} + +/** Event handler for the library USB Connection event. */ +void EVENT_USB_Device_Connect(void) +{ +} + +/** Event handler for the library USB Disconnection event. */ +void EVENT_USB_Device_Disconnect(void) +{ +} + +/** Event handler for the library USB Configuration Changed event. */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + bool ConfigSuccess = true; + + ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface); + ConfigSuccess &= HID_Device_ConfigureEndpoints(&MediaControl_HID_Interface); + + USB_Device_EnableSOFEvents(); +} + +/** Event handler for the library USB Control Request reception event. */ +void EVENT_USB_Device_ControlRequest(void) +{ + HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); + HID_Device_ProcessControlRequest(&MediaControl_HID_Interface); +} + +/** Event handler for the USB device Start Of Frame event. */ +void EVENT_USB_Device_StartOfFrame(void) +{ + HID_Device_MillisecondElapsed(&Keyboard_HID_Interface); + HID_Device_MillisecondElapsed(&MediaControl_HID_Interface); +} + +/** HID class driver callback function for the creation of HID reports to the host. + * + * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced + * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID + * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature + * \param[out] ReportData Pointer to a buffer where the created report should be stored + * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) + * + * \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent + */ + +bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, + uint8_t* const ReportID, + const uint8_t ReportType, + void* ReportData, + uint16_t* const ReportSize) +{ + int num_keys = process_keyboard(pressed_scancodes); + if (num_keys > MAX_SCANCODES) num_keys = MAX_SCANCODES; + + if (HIDInterfaceInfo == &Keyboard_HID_Interface) { + // host asks for a keyboard report + USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; + *ReportSize = sizeof(USB_KeyboardReport_Data_t); + for (int i=0; i<num_keys; i++) { + uint8_t sc = pressed_scancodes[i]; + if (!is_media_key(sc)) { + KeyboardReport->KeyCode[i] = sc; + } + } + } else if (HIDInterfaceInfo == &MediaControl_HID_Interface) { + // host asks for a media control report + USB_MediaReport_Data_t* MediaControlReport = (USB_MediaReport_Data_t*)ReportData; + *ReportSize = sizeof(USB_MediaReport_Data_t); + for (int i=0; i<num_keys; i++) { + uint8_t sc = pressed_scancodes[i]; + if (is_media_key(sc)) { + get_media_keys(sc, MediaControlReport); + } + } + } + return false; +} + +/** HID class driver callback function for the processing of HID reports from the host. + * + * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced + * \param[in] ReportID Report ID of the received report from the host + * \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature + * \param[in] ReportData Pointer to a buffer where the received report has been stored + * \param[in] ReportSize Size in bytes of the received HID report + */ +void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, + const uint8_t ReportID, + const uint8_t ReportType, + const void* ReportData, + const uint16_t ReportSize) +{ + uint8_t* data = (uint8_t*)ReportData; + if (ReportSize<4) return; + + hid_report_cmd(data); +} diff --git a/reform2-keyboard-fw/keyboard.h b/reform2-keyboard-fw/keyboard.h @@ -0,0 +1,167 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ + +#include <avr/io.h> +#include <avr/wdt.h> +#include <avr/power.h> +#include <avr/interrupt.h> +#include <stdbool.h> +#include <string.h> + +#include "Config/LUFAConfig.h" +#include "descriptors.h" +#include <LUFA/Drivers/USB/USB.h> +#include <LUFA/Platform/Platform.h> + +// some GPIO macros +#define output_low(port,pin) port &= ~(1<<pin) +#define output_high(port,pin) port |= (1<<pin) +#define set_input(portdir,pin) portdir &= ~(1<<pin) +#define set_output(portdir,pin) portdir |= (1<<pin) + +// Top row, left to right +#define MATRIX_DEFAULT_ROW_1 \ + KEY_ESCAPE,\ + KEY_F1,\ + KEY_F2,\ + KEY_F3,\ + KEY_F4,\ + KEY_F5,\ + KEY_F6,\ + KEY_F7,\ + KEY_F8,\ + KEY_F9,\ + KEY_F10,\ + KEY_F11,\ + KEY_F12,\ + KEY_CIRCLE + +// Second row +#define MATRIX_DEFAULT_ROW_2 \ + KEY_GRAVE_ACCENT_AND_TILDE,\ + KEY_1,\ + KEY_2,\ + KEY_3,\ + KEY_4,\ + KEY_5,\ + KEY_6,\ + KEY_7,\ + KEY_8,\ + KEY_9,\ + KEY_0,\ + KEY_MINUS_AND_UNDERSCORE,\ + KEY_EQUAL_AND_PLUS,\ + KEY_BACKSPACE + +// Third row +#define MATRIX_DEFAULT_ROW_3 \ + KEY_TAB,\ + KEY_Q,\ + KEY_W,\ + KEY_E,\ + KEY_R,\ + KEY_T,\ + KEY_Y,\ + KEY_U,\ + KEY_I,\ + KEY_O,\ + KEY_P,\ + KEY_OPENING_BRACKET_AND_OPENING_BRACE,\ + KEY_CLOSING_BRACKET_AND_CLOSING_BRACE,\ + KEY_BACKSLASH_AND_PIPE + +// Fourth row +#define MATRIX_DEFAULT_ROW_4 \ + HID_KEYBOARD_SC_LEFT_CONTROL,\ + HID_KEYBOARD_SC_APPLICATION,\ + KEY_A,\ + KEY_S,\ + KEY_D,\ + KEY_F,\ + KEY_G,\ + KEY_H,\ + KEY_J,\ + KEY_K,\ + KEY_L,\ + KEY_SEMICOLON_AND_COLON,\ + KEY_APOSTROPHE_AND_QUOTE,\ + KEY_ENTER + +// Fifth row +#define MATRIX_DEFAULT_ROW_5 \ + HID_KEYBOARD_SC_LEFT_SHIFT,\ + HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE,\ + KEY_Z,\ + KEY_X,\ + KEY_C,\ + KEY_V,\ + KEY_B,\ + KEY_N,\ + KEY_M,\ + HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN,\ + HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN,\ + KEY_SLASH_AND_QUESTION_MARK,\ + HID_KEYBOARD_SC_UP_ARROW,\ + HID_KEYBOARD_SC_RIGHT_SHIFT + +// Sixth row +#define MATRIX_DEFAULT_ROW_6 \ + HID_KEYBOARD_SC_EXECUTE,\ + HID_KEYBOARD_SC_LEFT_GUI,\ + HID_KEYBOARD_SC_RIGHT_CONTROL,\ + KEY_SPACE,\ + HID_KEYBOARD_SC_LEFT_ALT,\ + HID_KEYBOARD_SC_RIGHT_ALT,\ + KEY_SPACE,\ + HID_KEYBOARD_SC_PAGE_UP,\ + HID_KEYBOARD_SC_PAGE_DOWN,\ + HID_KEYBOARD_SC_LEFT_ARROW,\ + HID_KEYBOARD_SC_DOWN_ARROW,\ + HID_KEYBOARD_SC_RIGHT_ARROW + +// MediaController USB Report +typedef struct +{ + unsigned Play : 1; + unsigned Pause : 1; + unsigned FForward : 1; + unsigned Rewind : 1; + unsigned NextTrack : 1; + unsigned PreviousTrack : 1; + unsigned Stop : 1; + unsigned PlayPause : 1; + unsigned Mute : 1; + unsigned VolumeUp : 1; + unsigned VolumeDown : 1; + unsigned RESERVED : 5; +} ATTR_PACKED USB_MediaReport_Data_t; + +void setup_hardware(void); +void reset_keyboard_state(void); + +// LUFA USB handlers +void EVENT_USB_Device_Connect(void); +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); +void EVENT_USB_Device_StartOfFrame(void); + +bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, + uint8_t* const ReportID, + const uint8_t ReportType, + void* ReportData, + uint16_t* const ReportSize); + +void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, + const uint8_t ReportID, + const uint8_t ReportType, + const void* ReportData, + const uint16_t ReportSize); + +#endif diff --git a/reform2-keyboard-fw/matrix.h b/reform2-keyboard-fw/matrix.h @@ -0,0 +1,71 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#include "keyboard.h" + +// Every line of `matrix` is a row of the keyboard, starting from the top. +// Check keyboard.h for the definitions of the default rows. +uint8_t matrix[KBD_MATRIX_SZ] = { + MATRIX_DEFAULT_ROW_1, + MATRIX_DEFAULT_ROW_2, + MATRIX_DEFAULT_ROW_3, + MATRIX_DEFAULT_ROW_4, + MATRIX_DEFAULT_ROW_5, + MATRIX_DEFAULT_ROW_6, + + // Marker for layout editor (FIXME) + KBD_EDITOR_MARKER +}; + +// When holding down HYPER +uint8_t matrix_fn[KBD_MATRIX_SZ] = { + // Media keys on Hyper + F7-F12 + KEY_ESCAPE, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + HID_KEYBOARD_SC_MEDIA_BACKWARD, + HID_KEYBOARD_SC_MEDIA_PLAY, + HID_KEYBOARD_SC_MEDIA_FORWARD, + HID_KEYBOARD_SC_MEDIA_MUTE, + HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN, + HID_KEYBOARD_SC_MEDIA_VOLUME_UP, + KEY_CIRCLE, + + MATRIX_DEFAULT_ROW_2, + MATRIX_DEFAULT_ROW_3, + MATRIX_DEFAULT_ROW_4, + MATRIX_DEFAULT_ROW_5, + MATRIX_DEFAULT_ROW_6 +}; + +// Second layer (toggled by HYPER+CIRCLE) +uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = { + // Custom top row + KEY_ESCAPE, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + HID_KEYBOARD_SC_MEDIA_BACKWARD, + HID_KEYBOARD_SC_MEDIA_PLAY, + HID_KEYBOARD_SC_MEDIA_FORWARD, + HID_KEYBOARD_SC_MEDIA_MUTE, + HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN, + HID_KEYBOARD_SC_MEDIA_VOLUME_UP, + KEY_CIRCLE, + + MATRIX_DEFAULT_ROW_2, + MATRIX_DEFAULT_ROW_3, + MATRIX_DEFAULT_ROW_4, + MATRIX_DEFAULT_ROW_5, + MATRIX_DEFAULT_ROW_6 +}; diff --git a/reform2-keyboard-fw/matrix_v.h b/reform2-keyboard-fw/matrix_v.h @@ -0,0 +1,125 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#include "keyboard.h" + +// Every line of `matrix` is a row of the keyboard, starting from the top. +// Check keyboard.h for the definitions of the default rows. +uint8_t matrix[KBD_MATRIX_SZ] = { + MATRIX_DEFAULT_ROW_1, + MATRIX_DEFAULT_ROW_2, + MATRIX_DEFAULT_ROW_3, + MATRIX_DEFAULT_ROW_4, + MATRIX_DEFAULT_ROW_5, + + // Custom row six + HID_KEYBOARD_SC_LEFT_CONTROL, + HID_KEYBOARD_SC_LEFT_ALT, + HID_KEYBOARD_SC_LEFT_GUI, + KEY_SPACE, + KEY_SPACE, + KEY_SPACE, + KEY_SPACE, + HID_KEYBOARD_SC_RIGHT_ALT, + HID_KEYBOARD_SC_EXECUTE, + HID_KEYBOARD_SC_LEFT_ARROW, + HID_KEYBOARD_SC_DOWN_ARROW, + HID_KEYBOARD_SC_RIGHT_ARROW, + + // Marker for layout editor (FIXME) + KBD_EDITOR_MARKER +}; + +// When holding down HYPER +uint8_t matrix_fn[KBD_MATRIX_SZ] = { + // Custom top row + KEY_ESCAPE, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + HID_KEYBOARD_SC_MEDIA_BACKWARD, + HID_KEYBOARD_SC_MEDIA_PLAY, + HID_KEYBOARD_SC_MEDIA_FORWARD, + HID_KEYBOARD_SC_MEDIA_MUTE, + HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN, + HID_KEYBOARD_SC_MEDIA_VOLUME_UP, + KEY_CIRCLE, + + MATRIX_DEFAULT_ROW_2, + MATRIX_DEFAULT_ROW_3, + MATRIX_DEFAULT_ROW_4, + + // Custom row 5 + HID_KEYBOARD_SC_LEFT_SHIFT, + HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE, + KEY_Z, + KEY_X, + KEY_C, + KEY_V, + KEY_B, + KEY_N, + KEY_M, + HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN, + HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN, + KEY_SLASH_AND_QUESTION_MARK, + HID_KEYBOARD_SC_PAGE_UP, + HID_KEYBOARD_SC_RIGHT_SHIFT, + + // Custom row 6 + HID_KEYBOARD_SC_LEFT_CONTROL, + HID_KEYBOARD_SC_LEFT_ALT, + HID_KEYBOARD_SC_LEFT_GUI, + KEY_SPACE, + KEY_SPACE, + KEY_SPACE, + KEY_SPACE, + HID_KEYBOARD_SC_RIGHT_ALT, + HID_KEYBOARD_SC_EXECUTE, + HID_KEYBOARD_SC_HOME, + HID_KEYBOARD_SC_PAGE_DOWN, + HID_KEYBOARD_SC_END +}; + +// Second layer (toggled by HYPER+CIRCLE) +uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = { + // Custom top row + KEY_ESCAPE, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + HID_KEYBOARD_SC_MEDIA_BACKWARD, + HID_KEYBOARD_SC_MEDIA_PLAY, + HID_KEYBOARD_SC_MEDIA_FORWARD, + HID_KEYBOARD_SC_MEDIA_MUTE, + HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN, + HID_KEYBOARD_SC_MEDIA_VOLUME_UP, + KEY_CIRCLE, + + MATRIX_DEFAULT_ROW_2, + MATRIX_DEFAULT_ROW_3, + MATRIX_DEFAULT_ROW_4, + MATRIX_DEFAULT_ROW_5, + + // Custom row six + HID_KEYBOARD_SC_LEFT_CONTROL, + HID_KEYBOARD_SC_LEFT_ALT, + HID_KEYBOARD_SC_LEFT_GUI, + KEY_SPACE, + KEY_SPACE, + KEY_SPACE, + KEY_SPACE, + HID_KEYBOARD_SC_RIGHT_ALT, + HID_KEYBOARD_SC_EXECUTE, + HID_KEYBOARD_SC_LEFT_ARROW, + HID_KEYBOARD_SC_DOWN_ARROW, + HID_KEYBOARD_SC_RIGHT_ARROW +}; diff --git a/reform2-keyboard-fw/menu.c b/reform2-keyboard-fw/menu.c @@ -0,0 +1,186 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#include "backlight.h" +#include "constants.h" +#include "keyboard.h" +#include "menu.h" +#include "oled.h" +#include "powersave.h" +#include "remote.h" +#include "scancodes.h" + +int current_menu_y = 0; +int current_scroll_y = 0; + +#ifdef KBD_VARIANT_STANDALONE +#define MENU_NUM_ITEMS 5 +const MenuItem menu_items[] = { + { "Exit Menu ESC", KEY_ESCAPE }, + { "Key Backlight- F1", KEY_F1 }, + { "Key Backlight+ F2", KEY_F2 }, + { "System Status s", KEY_S }, + { "USB Flashing Mode x", KEY_X }, +}; +#else +#define MENU_NUM_ITEMS 9 +const MenuItem menu_items[] = { + { "Exit Menu ESC", KEY_ESCAPE }, + { "Power On 1", KEY_1 }, + { "Power Off 0", KEY_0 }, + { "Reset r", KEY_R }, + { "Battery Status b", KEY_B }, + { "Key Backlight- F1", KEY_F1 }, + { "Key Backlight+ F2", KEY_F2 }, + { "Wake SPC", KEY_SPACE }, + { "System Status s", KEY_S }, + + // Only needed for debugging. + // The keyboard will go to sleep when turning off + // main system power. + { "KBD Power-Off p", KEY_P }, +}; +#endif + +void reset_and_render_menu() { + current_scroll_y = 0; + current_menu_y = 0; + render_menu(current_scroll_y); +} + +void render_menu(int y) { + gfx_clear(); + gfx_invert_row(current_menu_y-y); + for (int i=0; i<MENU_NUM_ITEMS; i++) { + gfx_poke_str(0,i-y,menu_items[i].title); + } + gfx_on(); + gfx_flush(); +} + +int execute_menu_function(int y) { + if (y>=0 && y<MENU_NUM_ITEMS) { + return execute_meta_function(menu_items[y].keycode); + } + return execute_meta_function(KEY_ESCAPE); +} + +#define BOOTLOADER_START_ADDRESS ((0x8000-0x1000) >> 1) +void jump_to_bootloader(void) { + ((void (*)(void))BOOTLOADER_START_ADDRESS)(); +} + +// returns 1 for navigation function (stay in meta mode), 0 for terminal function +int execute_meta_function(int keycode) { + if (keycode == KEY_0) { + // TODO: are you sure? + anim_goodbye(); + remote_turn_off_som(); + keyboard_power_off(); + reset_keyboard_state(); + // Directly enter menu again + return 2; + } + else if (keycode == KEY_1) { + if (remote_turn_on_som()) { + anim_hello(); + } + kbd_brightness_init(); + return 0; + } + else if (keycode == KEY_R) { + // TODO: are you sure? + remote_reset_som(); + } + else if (keycode == KEY_SPACE) { + remote_wake_som(); + } + /*else if (keycode == KEY_V) { + remote_turn_off_aux(); + }*/ + else if (keycode == KEY_B) { + remote_get_voltages(); + return 0; + } + else if (keycode == KEY_S) { + remote_get_status(); + return 0; + } + else if (keycode == KEY_F1) { + kbd_brightness_dec(); + return 1; + } + else if (keycode == KEY_F2) { + kbd_brightness_inc(); + return 1; + } + else if (keycode == HID_KEYBOARD_SC_UP_ARROW) { + current_menu_y--; + if (current_menu_y<0) current_menu_y = 0; + if (current_menu_y<=current_scroll_y) current_scroll_y--; + if (current_scroll_y<0) current_scroll_y = 0; + render_menu(current_scroll_y); + return 1; + } + else if (keycode == HID_KEYBOARD_SC_DOWN_ARROW) { + current_menu_y++; + if (current_menu_y>=MENU_NUM_ITEMS) current_menu_y = MENU_NUM_ITEMS-1; + if (current_menu_y>=current_scroll_y+3) current_scroll_y++; + render_menu(current_scroll_y); + return 1; + } + else if (keycode == KEY_ENTER) { + return execute_menu_function(current_menu_y); + } + else if (keycode == KEY_ESCAPE) { + gfx_clear(); + gfx_flush(); + } + else if (keycode == KEY_X) { + jump_to_bootloader(); + } + + gfx_clear(); + gfx_flush(); + + return 0; +} + +void anim_hello(void) { + gfx_clear(); + gfx_on(); + for (int y=0; y<3; y++) { + for (int x=0; x<12; x++) { + gfx_poke(x+4,y+1,(5+y)*32+x); + gfx_flush(); + } + } + for (int y=0; y<0xff; y++) { + gfx_contrast(y); + Delay_MS(2); + } + for (int y=0; y<0xff; y++) { + gfx_contrast(0xff-y); + Delay_MS(2); + } +} + +void anim_goodbye(void) { + gfx_clear(); + gfx_on(); + for (int y=0; y<3; y++) { + for (int x=0; x<12; x++) { + gfx_poke(x+4,y+1,(5+y)*32+x); + } + } + for (int y=0; y<3; y++) { + for (int x=0; x<12; x++) { + gfx_poke(x+4,y+1,' '); + gfx_flush(); + } + } + gfx_off(); +} diff --git a/reform2-keyboard-fw/menu.h b/reform2-keyboard-fw/menu.h @@ -0,0 +1,22 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _MENU_H_ +#define _MENU_H_ + +typedef struct MenuItem { + char* title; + int keycode; +} MenuItem; + +void reset_and_render_menu(void); +void render_menu(int y); +int execute_menu_function(int y); +int execute_meta_function(int keycode); +void anim_hello(void); +void anim_goodbye(void); + +#endif diff --git a/reform2-keyboard-fw/oled.c b/reform2-keyboard-fw/oled.c @@ -0,0 +1,356 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +// OLED (SSD1306) rendering code. The OLED is interfaced via I2C. + +#include "oled.h" +#include "i2c.h" +#include <stdio.h> +#include <string.h> +#include <avr/pgmspace.h> +#include "gfx/font.c" + +int oledbrt = 0; + +// Write command sequence. +// Returns true on success. +static inline bool _send_cmd1(uint8_t cmd) { + bool res = false; + + if (i2c_start_write(SSD1306_ADDRESS)) { + // failed to start write + goto done; + } + + if (i2c_master_write(0x0 /* command byte follows */)) { + // failed to write control byte + goto done; + } + + if (i2c_master_write(cmd)) { + // failed to write command + goto done; + } + res = true; +done: + i2c_master_stop(); + return res; +} + +// Write 2-byte command sequence. +// Returns true on success +static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) { + if (!_send_cmd1(cmd)) { + //return false; + } + return _send_cmd1(opr); +} + +// Write 3-byte command sequence. +// Returns true on success +static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) { + if (!_send_cmd1(cmd)) { + //return false; + } + if (!_send_cmd1(opr1)) { + //return false; + } + return _send_cmd1(opr2); +} + +#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;} +#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} +#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} + +static void clear_display(void) { + matrix_clear(&display); + + // Clear all of the display bits (there can be random noise + // in the RAM on startup) + send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); + send_cmd3(ColumnAddr, 0, DisplayWidth - 1); + + if (i2c_start_write(SSD1306_ADDRESS)) { + goto done; + } + if (i2c_master_write(0x40)) { + // Data mode + goto done; + } + for (uint8_t row = 0; row < MatrixRows; ++row) { + for (uint8_t col = 0; col < DisplayWidth; ++col) { + i2c_master_write(0); + } + } + + display.dirty = false; + +done: + i2c_master_stop(); +} + +bool gfx_init(bool rotate) { + bool success = false; + rotate = false; // FIXME + + i2c_master_init(); + send_cmd1(DisplayOff); + send_cmd2(SetDisplayClockDiv, 0x80); + send_cmd2(SetMultiPlex, DisplayHeight - 1); + + send_cmd2(SetDisplayOffset, 0); + + send_cmd1(SetStartLine | 0x0); + send_cmd2(SetChargePump, 0x14 /* Enable */); + send_cmd2(SetMemoryMode, 0 /* horizontal addressing */); + + if (rotate) { + // the following Flip the display orientation 180 degrees + send_cmd1(SegRemap); + send_cmd1(ComScanInc); + } else { + // Flips the display orientation 0 degrees + send_cmd1(SegRemap | 0x1); + send_cmd1(ComScanDec); + } + + send_cmd2(SetComPins, 0x2); + send_cmd2(SetContrast, 0x8f); + send_cmd2(SetPreCharge, 0xf1); + send_cmd2(SetVComDetect, 0x40); + send_cmd1(DisplayAllOnResume); + send_cmd1(NormalDisplay); + send_cmd1(DeActivateScroll); + send_cmd1(DisplayOn); + + send_cmd2(SetContrast, 0); // Dim + + clear_display(); + + success = true; + + gfx_flush(); + +done: + return success; +} + +bool gfx_off(void) { + bool success = false; + + //send_cmd1(InvertDisplay); + send_cmd1(DisplayOff); + success = true; + +done: + return success; +} + +bool gfx_on(void) { + bool success = false; + + send_cmd1(NormalDisplay); + send_cmd1(DisplayOn); + success = true; + +done: + return success; +} + +void gfx_clear(void) { + for (int y=0; y<4; y++) { + for (int x=0; x<21; x++) { + gfx_poke(x,y,' '); + } + } + gfx_clear_invert(); +} + +void gfx_contrast(int c) { + send_cmd2(SetContrast, c); +done: + return; +} + +void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { + *matrix->cursor = c; + ++matrix->cursor; + + if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) { + // We went off the end; scroll the display upwards by one line + memmove(&matrix->display[0], &matrix->display[1], + MatrixCols * (MatrixRows - 1)); + matrix->cursor = &matrix->display[MatrixRows - 1][0]; + memset(matrix->cursor, ' ', MatrixCols); + } +} + +void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { + matrix->dirty = true; + + if (c == '\n') { + // Clear to end of line from the cursor and then move to the + // start of the next line + uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; + + while (cursor_col++ < MatrixCols) { + matrix_write_char_inner(matrix, ' '); + } + return; + } + + matrix_write_char_inner(matrix, c); +} + +void gfx_poke(uint8_t x, uint8_t y, uint8_t c) { + display.display[y][x] = c; +} + +void gfx_poke_str(uint8_t x, uint8_t y, char* str) { + int len = strlen(str); + if (len>21) len = 21; + // clip + if (y<0 || y>3) return; + + for (int xx=x; xx<x+len && xx<21; xx++) { + if (xx>=0 && xx<21) { + display.display[y][xx] = (uint8_t)str[xx-x]; + } + } +} + +void gfx_write_char(uint8_t c) { + matrix_write_char(&display, c); +} + +void matrix_write(struct CharacterMatrix *matrix, const char *data) { + const char *end = data + strlen(data); + while (data < end) { + matrix_write_char(matrix, *data); + ++data; + } +} + +void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) { + char data_ln[strlen(data)+2]; + snprintf(data_ln, sizeof(data_ln), "%s\n", data); + matrix_write(matrix, data_ln); +} + +void gfx_write(const char *data) { + matrix_write(&display, data); +} + +void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { + while (true) { + uint8_t c = pgm_read_byte(data); + if (c == 0) { + return; + } + matrix_write_char(matrix, c); + ++data; + } +} + +void gfx_write_P(const char *data) { + matrix_write_P(&display, data); +} + +void matrix_clear(struct CharacterMatrix *matrix) { + memset(matrix->display, ' ', sizeof(matrix->display)); + matrix->cursor = &matrix->display[0][0]; + matrix->dirty = true; +} + +void gfx_clear_screen(void) { + matrix_clear(&display); +} + +void gfx_clear_invert(void) { + for (int y=0;y<4;y++) { + for (int x=0;x<21;x++) { + display.invert[y][x] = 0; + } + } +} + +void gfx_invert_row(uint8_t y) { + if (y<0 || y>3) return; + for (int x=0;x<21;x++) { + display.invert[y][x] = 1; + } +} + +void matrix_render(struct CharacterMatrix *matrix) { + gfx_on(); + + // Move to the home position + send_cmd3(PageAddr, 0, MatrixRows - 1); + send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); + + if (i2c_start_write(SSD1306_ADDRESS)) { + //goto done; + } + if (i2c_master_write(0x40)) { + // Data mode + //goto done; + } + + for (uint8_t row = 0; row < MatrixRows; ++row) { + for (uint8_t col = 0; col < MatrixCols; ++col) { + const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth); + const uint8_t invert = matrix->invert[row][col]; + + for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) { + uint8_t colBits = pgm_read_byte(glyph + glyphCol); + if (invert) colBits = ~colBits; + i2c_master_write(colBits); + } + } + } + + matrix->dirty = false; + +done: + i2c_master_stop(); +} + +void matrix_render_direct(uint8_t* bitmap) { + gfx_on(); + + // Move to the home position + send_cmd3(PageAddr, 0, MatrixRows - 1); + send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); + + i2c_start_write(SSD1306_ADDRESS); + i2c_master_write(0x40); + + int c = 0; + for (uint16_t y=0; y<4; y++) { + for (uint16_t x=0; x<126; x++) { + i2c_master_write(bitmap[c++]); + } + } + +done: + i2c_master_stop(); +} + +void gfx_flush(void) { + matrix_render(&display); +} + +void oled_brightness_inc(void) { + oledbrt+=10; + if (oledbrt>=0xff) oledbrt = 0xff; + gfx_contrast(oledbrt); +} + +void oled_brightness_dec(void) { + oledbrt-=10; + if (oledbrt<0) oledbrt = 0; + gfx_contrast(oledbrt); +} diff --git a/reform2-keyboard-fw/oled.h b/reform2-keyboard-fw/oled.h @@ -0,0 +1,101 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _OLED_H_ +#define _OLED_H_ + +#include <stdbool.h> +#include <stdint.h> + +enum ssd1306_cmds { + DisplayOff = 0xAE, + DisplayOn = 0xAF, + + SetContrast = 0x81, + DisplayAllOnResume = 0xA4, + + DisplayAllOn = 0xA5, + NormalDisplay = 0xA6, + InvertDisplay = 0xA7, + SetDisplayOffset = 0xD3, + SetComPins = 0xda, + SetVComDetect = 0xdb, + SetDisplayClockDiv = 0xD5, + SetPreCharge = 0xd9, + SetMultiPlex = 0xa8, + SetLowColumn = 0x00, + SetHighColumn = 0x10, + SetStartLine = 0x40, + + SetMemoryMode = 0x20, + ColumnAddr = 0x21, + PageAddr = 0x22, + + ComScanInc = 0xc0, + ComScanDec = 0xc8, + SegRemap = 0xa0, + SetChargePump = 0x8d, + ExternalVcc = 0x01, + SwitchCapVcc = 0x02, + + ActivateScroll = 0x2f, + DeActivateScroll = 0x2e, + SetVerticalScrollArea = 0xa3, + RightHorizontalScroll = 0x26, + LeftHorizontalScroll = 0x27, + VerticalAndRightHorizontalScroll = 0x29, + VerticalAndLeftHorizontalScroll = 0x2a, +}; + +#define SSD1306_ADDRESS 0x3C + +#define DisplayHeight 32 +#define DisplayWidth 128 + +#define FontHeight 8 +#define FontWidth 6 + +#define MatrixRows (DisplayHeight / FontHeight) +#define MatrixCols (DisplayWidth / FontWidth) + +struct CharacterMatrix { + uint8_t display[MatrixRows][MatrixCols]; + uint8_t invert[MatrixRows][MatrixCols]; + uint8_t *cursor; + bool dirty; +}; + +struct CharacterMatrix display; + +void gfx_poke(uint8_t x, uint8_t y, uint8_t c); +void gfx_poke_str(uint8_t x, uint8_t y, char* str); +void gfx_clear_invert(void); +void gfx_invert_row(uint8_t y); +bool gfx_init(bool rotate); +void gfx_task(void); +bool gfx_off(void); +bool gfx_on(void); +void gfx_flush(void); +void gfx_clear(void); +void gfx_write_char(uint8_t c); +void gfx_write(const char *data); +void gfx_write_P(const char *data); +void gfx_clear_screen(void); +void gfx_contrast(int c); + +void matrix_clear(struct CharacterMatrix *matrix); +void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c); +void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c); +void matrix_write(struct CharacterMatrix *matrix, const char *data); +void matrix_write_ln(struct CharacterMatrix *matrix, const char *data); +void matrix_write_P(struct CharacterMatrix *matrix, const char *data); +void matrix_render(struct CharacterMatrix *matrix); +void matrix_render_direct(uint8_t* bitmap); + +void oled_brightness_inc(void); +void oled_brightness_dec(void); + +#endif diff --git a/reform2-keyboard-fw/powersave.c b/reform2-keyboard-fw/powersave.c @@ -0,0 +1,70 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#include <avr/io.h> +#include <avr/sleep.h> +#include "powersave.h" +#include "keyboard.h" +#include "oled.h" + +/* Setup the AVR to enter the Power-Down state to greatly save power. + * Configures all outputs to be in the low state if possible, and disables + * services like USB and Serial. + * + * Will leave the ports setup so that the Circle key row is being scanned + * so when the watchdog wakes up it can quickly check and go back to sleep if not + * Added by Chartreuse - 2021/08/14 + * + */ +void keyboard_power_off(void) +{ + USB_Disable(); // Stop USB stack so it doesn't wake us up + + // turn off backlight, but don't overwrite setting + OCR0A = 0; + + // Turn off OLED to save power + gfx_clear_screen(); + gfx_off(); + // Disable ADC to save even more power + ADCSRA=0; + + cli(); // No interrupts + + // Set all ports not floating if possible, leaving pullups alone + PORTB=0x3F; // Leave pull-up on all the columns on PB0-3, drive rows 2-3 high, 1-low + PORTC=0xC0; + PORTD=0xF0; // Keep pullup on PD5 like setup did, drive rows 4,5,6 high + PORTE=0x40; // Pullup on PE6 + PORTF=0xFF; // Pullups on PF (columns) + // ROW1 is the only row driven low and left low, thus is always ready to be read out + // We just need to check COL14 (PC6) if it is low (pressed) or high + + // Unfortunately the circle key is on COL14(PC6) which doesn't have pin change interrupt + // capabilities, so we need to wake up every so often to check if it is pressed, and + // if so bring us out of power-off + // We can use the Watchdog timer to do this. + + do { + wdt_reset(); + WDTCSR = (1<<WDCE) | (1<<WDE); // Enable writes to watchdog + WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (0<<WDP0); // Interrupt mode, 1s timeout + + // Enter Power-save mode + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_enable(); + sei(); // Enable interrupts so we can actually wake + sleep_cpu(); // Actually go to sleep + // Zzzzzz + sleep_disable(); // We've woken up + sei(); + // Check if circle key has been pressed (active-low) + // If not reset the watchdog and try again + } while(PINC&(1<<6)); + + // Resume and reinitialize hardware + setup_hardware(); +} diff --git a/reform2-keyboard-fw/powersave.h b/reform2-keyboard-fw/powersave.h @@ -0,0 +1,12 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _POWERSAVE_H_ +#define _POWERSAVE_H_ + +void keyboard_power_off(void); + +#endif diff --git a/reform2-keyboard-fw/remote.c b/reform2-keyboard-fw/remote.c @@ -0,0 +1,384 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#include <stdlib.h> +#include "remote.h" +#include "oled.h" +#include "powersave.h" +#include "constants.h" +#include "LUFA/Drivers/Peripheral/Serial.h" + +char response[64]; +int term_x = 0; +int term_y = 0; +float voltages[8]; +int alert_low_battery = 0; +int alert_blink = 0; +uint8_t remote_som_power_expected_state = 0; + +void empty_serial(void) { + int clock = 0; + while (Serial_ReceiveByte()>=0 && clock<100) { + // flush serial + clock++; + } +} + +int remote_receive_string(int print) { + char done = 0; + int32_t clock = 0; + int res_x = 0; + response[0] = 0; + + while (!done) { + int16_t chr = -1; + clock = 0; + while (chr==-1 || chr==0) { + chr=Serial_ReceiveByte(); + clock++; + if (clock>500000) goto timeout; + } + int poke_chr = chr; + if (chr=='\n') poke_chr=' '; + if (chr!='\r') { + if (print) { + gfx_poke(term_x,term_y,poke_chr); + gfx_poke(term_x+1,term_y,' '); + term_x++; + if (term_x>=20) { + term_x=0; + term_y++; + if (term_y>=3) { + term_y=0; + } + } + } + if (res_x<63) { + response[res_x++] = chr; + response[res_x] = 0; + } + } + if (chr=='\r') done = 1; + } +timeout: + if (!done && print) gfx_poke(20,0,'T'); + empty_serial(); + if (print) { + gfx_flush(); + } + return done; +} + +int remote_try_wakeup(void) { + int ok = 0; + char buf[64]; + +#ifdef KBD_VARIANT_STANDALONE + // there's no remote + return 0; +#endif + + for (int i=0; i<1000; i++) { + if (i%10 == 0) { + gfx_clear(); + sprintf(buf, "Waking up LPC... %d%%", i/4); + gfx_poke_str(0, 0, buf); + gfx_flush(); + } + + Serial_SendByte('a'); + Serial_SendByte('\r'); + + if (Serial_ReceiveByte()>0) { + remote_receive_string(0); + ok = 1; + break; + } + + Delay_MS(25); + } + Serial_SendByte('\r'); + Delay_MS(10); + while (remote_receive_string(0)) { + Delay_MS(25); + } + + return ok; +} + +int remote_try_command(char* cmd, int print_response) { + int ok = 0; + +#ifdef KBD_VARIANT_STANDALONE + // there's no remote + return 0; +#endif + + empty_serial(); + for (int tries=0; tries<2; tries++) { + for (int i=0; i<strlen(cmd); i++) { + Serial_SendByte(cmd[i]); + } + Serial_SendByte('\r'); + Delay_MS(1); + + if (print_response) { + term_x = 0; + term_y = 0; + } + ok = remote_receive_string(print_response); + + if (!ok && tries == 0) { + remote_try_wakeup(); + empty_serial(); + } + if (ok) break; + } + if (!ok) { + gfx_clear(); + gfx_poke_str(0, 0, "No response from LPC."); + gfx_flush(); + } + + empty_serial(); + return ok; +} + +void insert_bat_icon(char* str, int x, float v) { + char icon = 0; + if (v>=3.3) { + icon = 8; + } else if (v>=3.1) { + icon = 6; + } else if (v>=3.0) { + icon = 4; + } else if (v>=2.9) { + icon = 2; + } else { + icon = 0; + } + str[x] = 4*32+icon; + str[x+1] = 4*32+icon+1; +} + +int remote_get_voltages(void) { + term_x = 0; + term_y = 0; + + float bat_volts = 0; + float bat_amps = 0; + char bat_gauge[5] = {0,0,0,0,0}; + + int ok = remote_try_command("c", 0); + if (!ok) return ok; + + // lpc format: 32 32 32 32 32 32 32 32 mA 0256mV26143 ???% P1 + // | | | | | | | | | | | | | + // 0 3 6 9 12 15 18 21 24| | | | + // 26 33 39 44 + // | + // `- can be a minus + float sum_volts = 0; + + for (int i=0; i<8; i++) { + voltages[i] = ((float)((response[i*3]-'0')*10 + (response[i*3+1]-'0')))/10.0; + if (voltages[i]<0) voltages[i]=0; + if (voltages[i]>=10) voltages[i]=9.9; + sum_volts += voltages[i]; + } + + int amps_offset = 3*8+2; + // cut off string + response[amps_offset+5]=0; + bat_amps = ((float)atoi(&response[amps_offset]))/1000.0; + int volts_offset = amps_offset+5+2; + response[volts_offset+5]=0; + bat_volts = ((float)atoi(&response[volts_offset]))/1000.0; + int gauge_offset = volts_offset+5+1; + strncpy(bat_gauge, &response[gauge_offset], 4); + + char* power_str = " "; + int syspower_offset = gauge_offset+5; + char power_digit = response[syspower_offset+1]; + if (power_digit == '1') { + power_str = " On"; + } else if (power_digit == '0') { + power_str = "Off"; + } + + // plot + gfx_clear(); + char str[32]; + + sprintf(str,"[] %.1f [] %.1f %s",voltages[0],voltages[4],bat_gauge); + insert_bat_icon(str,0,voltages[0]); + insert_bat_icon(str,8,voltages[4]); + gfx_poke_str(0,0,str); + + sprintf(str,"[] %.1f [] %.1f %s",voltages[1],voltages[5],power_str); + insert_bat_icon(str,0,voltages[1]); + insert_bat_icon(str,8,voltages[5]); + gfx_poke_str(0,1,str); + + if (bat_amps>=0) { + sprintf(str,"[] %.1f [] %.1f %2.3fA",voltages[2],voltages[6],bat_amps); + } else { + sprintf(str,"[] %.1f [] %.1f %2.2fA",voltages[2],voltages[6],bat_amps); + } + insert_bat_icon(str,0,voltages[2]); + insert_bat_icon(str,8,voltages[6]); + gfx_poke_str(0,2,str); + + sprintf(str,"[] %.1f [] %.1f %2.2fV",voltages[3],voltages[7],bat_volts); + insert_bat_icon(str,0,voltages[3]); + insert_bat_icon(str,8,voltages[7]); + gfx_poke_str(0,3,str); + gfx_flush(); + + return ok; +} + +int remote_check_for_low_battery(void) { + char bat_gauge[5] = {0,0,0,0,0}; + + alert_low_battery = 0; + empty_serial(); + + Serial_SendByte('c'); + Serial_SendByte('\r'); + Delay_MS(1); + int ok = remote_receive_string(0); + if (!ok) return ok; + + for (int i=0; i<8; i++) { + // TODO: only accept digits + voltages[i] = ((float)((response[i*3]-'0')*10 + (response[i*3+1]-'0')))/10.0; + if (voltages[i]<0) voltages[i]=0; + if (voltages[i]>=10) voltages[i]=9.9; + if (voltages[i]<3.0) { + alert_low_battery = 1; + } + } + + int gauge_offset = 3*8+2+5+2+5+1; + strncpy(bat_gauge, &response[gauge_offset], 3); + + if (bat_gauge[0] == '?') { + // battery charge level unknown + } else { + int percent = atoi(bat_gauge); + if (percent<10) { + alert_low_battery = 1; + } + } + + int syspower_offset = gauge_offset+5; + if (response[syspower_offset] == 'P') { + char digit = response[syspower_offset+1]; + if (digit == '0' || digit == '1') { + int is_computer_on = (digit == '1'); + if (!is_computer_on && remote_som_power_expected_state == 1) { + // LPC says the computer is off, but we didn't expect it to be. + // the only way this happens is if LPC turned off the system + // due to a low battery condition. + // + // The keyboard will then go to sleep accordingly. + + keyboard_power_off(); + } + remote_som_power_expected_state = is_computer_on; + } + } + + return ok; +} + +int remote_get_status(void) { + gfx_clear(); + empty_serial(); + + gfx_poke_str(0, 2, "MNT Reform Keyboard"); + gfx_poke_str(0, 3, KBD_FW_REV); + gfx_on(); + gfx_flush(); + +#ifndef KBD_VARIANT_STANDALONE + int ok = remote_try_command("s", 1); + return ok; +#endif + return 1; +} + +int remote_turn_on_som(void) { + gfx_clear(); + + int ok = remote_try_command("1p", 0); + if (!ok) { + // FIXME what is remote_som_power_expected_state? + return ok; + } + + remote_som_power_expected_state = 1; + return ok; +} + +int remote_turn_off_som(void) { + int ok = remote_try_command("0p", 0); + if (!ok) return ok; + + remote_som_power_expected_state = 0; + return ok; +} + +int remote_reset_som(void) { + return remote_try_command("2p", 0); +} + +int remote_wake_som(void) { + int ok = remote_try_command("1w", 0); + if (!ok) return ok; + ok = remote_try_command("0w", 0); + return ok; +} + +int remote_turn_off_aux(void) { + return remote_try_command("3p", 0); +} + +int remote_turn_on_aux(void) { + return remote_try_command("4p", 0); +} + +int remote_report_voltages(void) { + return remote_try_command("0c", 0); +} + +int remote_enable_som_uart(void) { + return remote_try_command("1u", 0); +} + +int remote_disable_som_uart(void) { + return remote_try_command("0u", 0); +} + +void remote_process_alerts(void) { + if (alert_low_battery) { + gfx_on(); + for (int x=8;x<=11;x++) { + gfx_poke( x,0,' '); + } + if (alert_blink) { + gfx_poke( 9,0,4*32+2); + gfx_poke(10,0,4*32+3); + } + gfx_flush(); + } + alert_blink = 1-alert_blink; +} + +void remote_init(void) { + Serial_Init(57600, false); +} diff --git a/reform2-keyboard-fw/remote.h b/reform2-keyboard-fw/remote.h @@ -0,0 +1,29 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +#ifndef _REMOTE_H_ +#define _REMOTE_H_ + +void empty_serial(void); +int remote_receive_string(int print); +int remote_try_wakeup(void); +int remote_try_command(char* cmd, int print_response); +int remote_get_voltages(void); +int remote_check_for_low_battery(void); +int remote_get_status(void); +int remote_turn_on_som(void); +int remote_turn_off_som(void); +int remote_reset_som(void); +int remote_wake_som(void); +int remote_turn_off_aux(void); +int remote_turn_on_aux(void); +int remote_report_voltages(void); +int remote_enable_som_uart(void); +int remote_disable_som_uart(void); +void remote_process_alerts(void); +void remote_init(void); + +#endif diff --git a/reform2-keyboard-fw/scancodes.h b/reform2-keyboard-fw/scancodes.h @@ -1,3 +1,14 @@ +/* + MNT Reform 2.0 Keyboard Firmware + See keyboard.c for Copyright + SPDX-License-Identifier: MIT +*/ + +// Find additional codes in lufa-master/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h + +#ifndef _SCANCODES_H_ +#define _SCANCODES_H_ + #define KEY_A 0x04 #define KEY_B 0x05 #define KEY_C 0x06 @@ -114,3 +125,7 @@ #define KEY_MUTE 0x7F #define KEY_VOLUME_UP 0x80 #define KEY_VOLUME_DOWN 0x81 + +#define KEY_CIRCLE 0xA4 // "EXSEL" + +#endif diff --git a/reform2-keyboard-fw/ssd1306.c b/reform2-keyboard-fw/ssd1306.c @@ -1,304 +0,0 @@ -#include "ssd1306.h" -#include "i2c.h" -#include <string.h> -#include <avr/pgmspace.h> -#include "gfx/font.c" - -// Write command sequence. -// Returns true on success. -static inline bool _send_cmd1(uint8_t cmd) { - bool res = false; - - if (i2c_start_write(SSD1306_ADDRESS)) { - //xprintf("failed to start write to %d\n", SSD1306_ADDRESS); - goto done; - } - - if (i2c_master_write(0x0 /* command byte follows */)) { - //print("failed to write control byte\n"); - - goto done; - } - - if (i2c_master_write(cmd)) { - //xprintf("failed to write command %d\n", cmd); - goto done; - } - res = true; -done: - i2c_master_stop(); - return res; -} - -// Write 2-byte command sequence. -// Returns true on success -static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) { - if (!_send_cmd1(cmd)) { - //return false; - } - return _send_cmd1(opr); -} - -// Write 3-byte command sequence. -// Returns true on success -static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) { - if (!_send_cmd1(cmd)) { - //return false; - } - if (!_send_cmd1(opr1)) { - //return false; - } - return _send_cmd1(opr2); -} - -#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;} -#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} -#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} - -static void clear_display(void) { - matrix_clear(&display); - - // Clear all of the display bits (there can be random noise - // in the RAM on startup) - send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); - send_cmd3(ColumnAddr, 0, DisplayWidth - 1); - - if (i2c_start_write(SSD1306_ADDRESS)) { - goto done; - } - if (i2c_master_write(0x40)) { - // Data mode - goto done; - } - for (uint8_t row = 0; row < MatrixRows; ++row) { - for (uint8_t col = 0; col < DisplayWidth; ++col) { - i2c_master_write(0); - } - } - - display.dirty = false; - -done: - i2c_master_stop(); -} - -bool gfx_init(bool rotate) { - bool success = false; - rotate = false; // FIXME - - i2c_master_init(); - send_cmd1(DisplayOff); - send_cmd2(SetDisplayClockDiv, 0x80); - send_cmd2(SetMultiPlex, DisplayHeight - 1); - - send_cmd2(SetDisplayOffset, 0); - - send_cmd1(SetStartLine | 0x0); - send_cmd2(SetChargePump, 0x14 /* Enable */); - send_cmd2(SetMemoryMode, 0 /* horizontal addressing */); - - if (rotate) { - // the following Flip the display orientation 180 degrees - send_cmd1(SegRemap); - send_cmd1(ComScanInc); - } else { - // Flips the display orientation 0 degrees - send_cmd1(SegRemap | 0x1); - send_cmd1(ComScanDec); - } - - send_cmd2(SetComPins, 0x2); - send_cmd2(SetContrast, 0x8f); - send_cmd2(SetPreCharge, 0xf1); - send_cmd2(SetVComDetect, 0x40); - send_cmd1(DisplayAllOnResume); - send_cmd1(NormalDisplay); - send_cmd1(DeActivateScroll); - send_cmd1(DisplayOn); - - send_cmd2(SetContrast, 0); // Dim - - clear_display(); - - success = true; - - gfx_flush(); - -done: - return success; -} - -bool gfx_off(void) { - bool success = false; - - //send_cmd1(InvertDisplay); - send_cmd1(DisplayOff); - success = true; - -done: - return success; -} - -bool gfx_on(void) { - bool success = false; - - send_cmd1(NormalDisplay); - send_cmd1(DisplayOn); - success = true; - -done: - return success; -} - -void gfx_contrast(int c) { - send_cmd2(SetContrast, c); -done: - return; -} - -void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { - *matrix->cursor = c; - ++matrix->cursor; - - if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) { - // We went off the end; scroll the display upwards by one line - memmove(&matrix->display[0], &matrix->display[1], - MatrixCols * (MatrixRows - 1)); - matrix->cursor = &matrix->display[MatrixRows - 1][0]; - memset(matrix->cursor, ' ', MatrixCols); - } -} - -void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { - matrix->dirty = true; - - if (c == '\n') { - // Clear to end of line from the cursor and then move to the - // start of the next line - uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; - - while (cursor_col++ < MatrixCols) { - matrix_write_char_inner(matrix, ' '); - } - return; - } - - matrix_write_char_inner(matrix, c); -} - -void gfx_poke(uint8_t x, uint8_t y, uint8_t c) { - display.display[y][x] = c; -} - -void gfx_poke_str(uint8_t x, uint8_t y, char* str) { - int len = strlen(str); - if (len>21) len = 21; - // clip - if (y<0 || y>3) return; - - for (int xx=x; xx<x+len && xx<21; xx++) { - if (xx>=0 && xx<21) { - display.display[y][xx] = (uint8_t)str[xx-x]; - } - } -} - -void gfx_write_char(uint8_t c) { - matrix_write_char(&display, c); -} - -void matrix_write(struct CharacterMatrix *matrix, const char *data) { - const char *end = data + strlen(data); - while (data < end) { - matrix_write_char(matrix, *data); - ++data; - } -} - -void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) { - char data_ln[strlen(data)+2]; - snprintf(data_ln, sizeof(data_ln), "%s\n", data); - matrix_write(matrix, data_ln); -} - -void gfx_write(const char *data) { - matrix_write(&display, data); -} - -void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { - while (true) { - uint8_t c = pgm_read_byte(data); - if (c == 0) { - return; - } - matrix_write_char(matrix, c); - ++data; - } -} - -void gfx_write_P(const char *data) { - matrix_write_P(&display, data); -} - -void matrix_clear(struct CharacterMatrix *matrix) { - memset(matrix->display, ' ', sizeof(matrix->display)); - matrix->cursor = &matrix->display[0][0]; - matrix->dirty = true; -} - -void gfx_clear_screen(void) { - matrix_clear(&display); -} - -void gfx_clear_invert(void) { - for (int y=0;y<4;y++) { - for (int x=0;x<21;x++) { - display.invert[y][x] = 0; - } - } -} - -void gfx_invert_row(uint8_t y) { - if (y<0 || y>3) return; - for (int x=0;x<21;x++) { - display.invert[y][x] = 1; - } -} - -void matrix_render(struct CharacterMatrix *matrix) { - gfx_on(); - - // Move to the home position - send_cmd3(PageAddr, 0, MatrixRows - 1); - send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); - - if (i2c_start_write(SSD1306_ADDRESS)) { - //goto done; - } - if (i2c_master_write(0x40)) { - // Data mode - //goto done; - } - - for (uint8_t row = 0; row < MatrixRows; ++row) { - for (uint8_t col = 0; col < MatrixCols; ++col) { - const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth); - const uint8_t invert = matrix->invert[row][col]; - - for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) { - uint8_t colBits = pgm_read_byte(glyph + glyphCol); - if (invert) colBits = ~colBits; - i2c_master_write(colBits); - } - } - } - - matrix->dirty = false; - -done: - i2c_master_stop(); -} - -void gfx_flush(void) { - matrix_render(&display); -} diff --git a/reform2-keyboard-fw/ssd1306.h b/reform2-keyboard-fw/ssd1306.h @@ -1,96 +0,0 @@ -#pragma once - -#include <stdbool.h> -#include <stdio.h> -//#include "action.h" - -enum ssd1306_cmds { - DisplayOff = 0xAE, - DisplayOn = 0xAF, - - SetContrast = 0x81, - DisplayAllOnResume = 0xA4, - - DisplayAllOn = 0xA5, - NormalDisplay = 0xA6, - InvertDisplay = 0xA7, - SetDisplayOffset = 0xD3, - SetComPins = 0xda, - SetVComDetect = 0xdb, - SetDisplayClockDiv = 0xD5, - SetPreCharge = 0xd9, - SetMultiPlex = 0xa8, - SetLowColumn = 0x00, - SetHighColumn = 0x10, - SetStartLine = 0x40, - - SetMemoryMode = 0x20, - ColumnAddr = 0x21, - PageAddr = 0x22, - - ComScanInc = 0xc0, - ComScanDec = 0xc8, - SegRemap = 0xa0, - SetChargePump = 0x8d, - ExternalVcc = 0x01, - SwitchCapVcc = 0x02, - - ActivateScroll = 0x2f, - DeActivateScroll = 0x2e, - SetVerticalScrollArea = 0xa3, - RightHorizontalScroll = 0x26, - LeftHorizontalScroll = 0x27, - VerticalAndRightHorizontalScroll = 0x29, - VerticalAndLeftHorizontalScroll = 0x2a, -}; - -// Controls the SSD1306 128x32 OLED display via i2c - -#ifndef SSD1306_ADDRESS -#define SSD1306_ADDRESS 0x3C -#endif - -#define DisplayHeight 32 -#define DisplayWidth 128 - -#define FontHeight 8 -#define FontWidth 6 - -#define MatrixRows (DisplayHeight / FontHeight) -#define MatrixCols (DisplayWidth / FontWidth) - -struct CharacterMatrix { - uint8_t display[MatrixRows][MatrixCols]; - uint8_t invert[MatrixRows][MatrixCols]; - uint8_t *cursor; - bool dirty; -}; - -struct CharacterMatrix display; - -void gfx_poke(uint8_t x, uint8_t y, uint8_t c); -void gfx_poke_str(uint8_t x, uint8_t y, char* str); -void gfx_clear_invert(void); -void gfx_invert_row(uint8_t y); -bool gfx_init(bool rotate); -void gfx_task(void); -bool gfx_off(void); -bool gfx_on(void); -void gfx_flush(void); -void gfx_write_char(uint8_t c); -void gfx_write(const char *data); -void gfx_write_P(const char *data); -void gfx_clear_screen(void); -void gfx_contrast(int c); - -void gfx_task_user(void); - -void matrix_clear(struct CharacterMatrix *matrix); -void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c); -void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c); -void matrix_write(struct CharacterMatrix *matrix, const char *data); -void matrix_write_ln(struct CharacterMatrix *matrix, const char *data); -void matrix_write_P(struct CharacterMatrix *matrix, const char *data); -void matrix_render(struct CharacterMatrix *matrix); - -//bool process_record_gfx(uint16_t keycode, keyrecord_t *record);