Enhanced keyboard/OLED firmware

I spent the last few nights hacking on the keyboard firmware, and posted my branch here:

The changes are pretty extensive, because I split the single “Keyboard” source file into a half dozen modules so I could understand them better. (I know this will be annoying to the authors. I’m sorry.) Then I added a bunch of features to the display and the hidraw interface (/dev/hidraw2) which added about 2KB to the binary image and 400 bytes to the RAM usage (now 53% and 52%, respectively).

Here’s a list of the enhancements I made:

  • switched out the 6x8 font for an Apple-II-inspired font (128 ASCII characters only)
    • you can switch back to the original with a #define at the top of display.c
  • added a larger 8x16 font (bizcat) that can be selected by the hidraw interface
  • compressed the MNT reform logo, and pulled it out of the font, but kept it animated (because that looks cool)
  • new hidraw commands:
    • UXPW: display the battery status as if the user pressed circle-B
    • UXST: display the keyboard status as if the user pressed circle-S
    • WCLR: clear the OLED display
    • FONT0: select the default 6x8 font (21x4 characters)
    • FONT1: select the bizcat 8x16 font (16x2 characters)
    • WRIT (text): write to the OLED display as if it were a scrolling terminal, with extra escape codes listed below
    • WBIT (u16 LE offset) (bytes): write a bitmap directly into the 512-byte display memory, starting at offset
    • WRLE (u16 LE offset) (bytes): write RLE-encoded data into the 512-byte display memory, starting at offset
  • special escape codes in WRIT to make it easier to write a daemon that displays battery status, using byte 255 (0xff) as an escape:
    • C: clear the display
    • I: turn on inverted text mode
    • N: turn off inverted text mode
    • +: switch to bizcat 8x16 font
    • -: switch to default 6x8 font
    • B: 2-character-wide battery icon showing overall battery level
    • A: 1-character-wide lightning bolt if the battery is charging, or a space otherwise
    • P: 3-character-wide battery percentage (" 0" to “100”)

To draw a tiny square in the upper right corner (offset 120):

  • echo -ne "xWBIT\x78\x00\xff\x81\x81\x81\x81\x81\x81\xff" > /dev/hidraw2

Or via RLE mode:

  • echo -ne "xWRLE\x78\x00\x01\xff\x86\x81\x01\xff" > /dev/hidraw2

I doubt the RLE mode is interesting outside of displaying the boot logo, but the very simple encoding is described at the bottom of display.c.

And here’s the shell command I ran to get the current date/time and battery status displayed in the large font, using escape codes:

  • echo -ne "xWRIT\xff+\xffC"$(date '+%d %b')" "$(date +%H:%M)" \xffB \xffA \xffP%" > /dev/hidraw2

I would love if some or all of these enhancements were pulled into the primary MNT driver, but I understand that I may have just moved the code around too much. Hopefully others will find this useful though. :slight_smile:

10 Likes