Making another split keyboard: Lily58 QMK edition


With the previous success (see part1, part1-a and part2) in making a bluetooth keyboard, I decided to make another keyboard with a different approach:

My excuse for building this keyboard was that my blue switches keyboard may be too noisy for the office, and the work desktop has no bluetooth (I know, sad, right?). The plan for this one was:

  • Quieter Red gateron switches rather than blue
  • USB powered rather than battery power, which allows for WS2812B LEDs and OLED display
  • Not a lot of assembly required (nRFmicro was a bit of a pain), so I chose the Pro Micro as a controller board instead. Also, since this is going to be wired anyway, no need for bluetooth either
  • Since the ProMicro is an 8-bit microcontroller and not supported by ZMK, I had to go for QMK for the firmware, which supports a wide range of boards

Building the keyboard

Basically tried to follow the guide here, which is in Japanese, but the pictures are more than enough guidance… Anyway, here are some pictures from the process:

Flashing QMK onto the controller boards

The fun part was flashing the keyboard’s controller boards, and while all the information is on the documentation page, what’s a project without some issues?

First, I tried to use the qmk package from the community repos, i.e. sudo pacman -S qmk and followed the documentation on building firmware, but I ran into problems:

╰─ qmk compile -kb lily58/rev1 -km default                                                                                                                   ─╯
Ψ Compiling keymap with make --jobs=1 lily58/rev1:default


QMK Firmware 0.16.9
Making lily58/rev1 with keymap default

avr-gcc (GCC) 12.1.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Generating: .build/obj_lily58_rev1/src/info_config.h                                                [OK]
Generating: .build/obj_lily58_rev1/src/default_keyboard.h                                           [OK]
Generating: .build/obj_lily58_rev1/src/layouts.h                                                    [OK]
Compiling: keyboards/lily58/lib/rgb_state_reader.c                                                  [OK]
Compiling: keyboards/lily58/lib/layer_state_reader.c                                                [OK]
Compiling: keyboards/lily58/lib/logo_reader.c                                                       [OK]
Compiling: keyboards/lily58/lib/keylogger.c                                                         [OK]
Compiling: keyboards/lily58/lily58.c                                                                [OK]
Compiling: keyboards/lily58/rev1/rev1.c                                                             [OK]
Compiling: keyboards/lily58/keymaps/default/keymap.c                                                [OK]
Compiling: quantum/quantum.c                                                                        [OK]
Compiling: quantum/send_string.c                                                                    [OK]
Compiling: quantum/bitwise.c                                                                        [OK]
Compiling: quantum/led.c                                                                            [OK]
Compiling: quantum/action.c                                                                         [OK]
Compiling: quantum/action_layer.c                                                                   [OK]
Compiling: quantum/action_tapping.c                                                                 [OK]
Compiling: quantum/action_util.c                                                                    [OK]
Compiling: quantum/eeconfig.c                                                                       [OK]
Compiling: quantum/keyboard.c                                                                       [OK]
Compiling: quantum/keymap_common.c                                                                  [OK]
Compiling: quantum/keycode_config.c                                                                 [OK]
Compiling: quantum/sync_timer.c                                                                     [OK]
Compiling: quantum/logging/debug.c                                                                  [OK]
Compiling: quantum/logging/sendchar.c                                                               [OK]
Compiling: quantum/bootmagic/magic.c                                                                [OK]
Compiling: quantum/matrix_common.c                                                                  [OK]
Compiling: quantum/matrix.c                                                                         [OK]
Compiling: quantum/debounce/sym_defer_g.c                                                           [OK]
Compiling: quantum/split_common/split_util.c                                                        [OK]
Compiling: quantum/split_common/transport.c                                                         [OK]
Compiling: quantum/split_common/transactions.c                                                      [OK]
Compiling: quantum/main.c                                                                           [OK]
Compiling: quantum/crc.c                                                                            [OK]
Compiling: drivers/oled/ssd1306_sh1106.c                                                            [OK]
Compiling: quantum/process_keycode/process_magic.c                                                  [OK]
Compiling: quantum/process_keycode/process_grave_esc.c                                              [OK]
Compiling: quantum/process_keycode/process_space_cadet.c                                            [OK]
Compiling: platforms/avr/drivers/i2c_master.c                                                      In function 'i2c_start_impl',
    inlined from 'i2c_start' at platforms/avr/drivers/i2c_master.c:104:18:
platforms/avr/drivers/i2c_master.c:61:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   61 |     TWCR = 0;
      |          ^
platforms/avr/drivers/i2c_master.c:63:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   63 |     TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
      |          ^
In file included from /usr/avr/include/avr/io.h:99,
                 from platforms/avr/pin_defs.h:18,
                 from platforms/pin_defs.h:22,
                 from quantum/config_common.h:20,
                 from ./keyboards/lily58/config.h:21,
                 from <command-line>:
platforms/avr/drivers/i2c_master.c:66:14: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   66 |     while (!(TWCR & (1 << TWINT))) {
      |              ^~~~
platforms/avr/drivers/i2c_master.c:73:11: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   73 |     if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) {
      |           ^~~~~~~~~
platforms/avr/drivers/i2c_master.c:73:47: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   73 |     if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) {
      |                                               ^~~~~~~~~
platforms/avr/drivers/i2c_master.c:78:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   78 |     TWDR = address;
      |          ^
platforms/avr/drivers/i2c_master.c:80:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   80 |     TWCR = (1 << TWINT) | (1 << TWEN);
      |          ^
platforms/avr/drivers/i2c_master.c:83:14: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   83 |     while (!(TWCR & (1 << TWINT))) {
      |              ^~~~
platforms/avr/drivers/i2c_master.c:90:30: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   90 |     uint8_t twst = TW_STATUS & 0xF8;
      |                              ^
In function 'i2c_stop',
    inlined from 'i2c_transmit' at platforms/avr/drivers/i2c_master.c:166:5:
platforms/avr/drivers/i2c_master.c:299:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
  299 |     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
      |          ^
In function 'i2c_stop',
    inlined from 'i2c_receive' at platforms/avr/drivers/i2c_master.c:188:5:
platforms/avr/drivers/i2c_master.c:299:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
  299 |     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
      |          ^
In function 'i2c_stop',
    inlined from 'i2c_writeReg' at platforms/avr/drivers/i2c_master.c:203:5:
platforms/avr/drivers/i2c_master.c:299:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
  299 |     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
      |          ^
In function 'i2c_stop',
    inlined from 'i2c_writeReg16' at platforms/avr/drivers/i2c_master.c:222:5:
platforms/avr/drivers/i2c_master.c:299:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
  299 |     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
      |          ^
In function 'i2c_stop',
    inlined from 'i2c_readReg' at platforms/avr/drivers/i2c_master.c:255:5:
platforms/avr/drivers/i2c_master.c:299:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
  299 |     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
      |          ^
In function 'i2c_stop',
    inlined from 'i2c_readReg16' at platforms/avr/drivers/i2c_master.c:292:5:
platforms/avr/drivers/i2c_master.c:299:10: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
  299 |     TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
      |          ^
cc1: all warnings being treated as errors
 [ERRORS]
 |
 |
 |
make[1]: *** [builddefs/common_rules.mk:456: .build/obj_lily58_rev1_default/i2c_master.o] Error 1
Make finished with errors
make: *** [Makefile:413: lily58/rev1:default] Error 1

After that, I had to go back to the the getting started guide and use Windows (the horror), turns out that QMK MSYS is basically the same thing, so I just used that to create a new keymap and since I was already using windows I figured I should also use the QMK Toolbox

Also, I figured out that it is possible to make the already soldered ProMicro boards go into bootloader mode by pressing the shift + B keys on the left half and shift + N keys on the right half of the keyboard. Another fun fact is that you flash the same .hex file onto both boards, so no need to have per half binaries (as opposed to the last keyboard)

Here are my configuration files, in case anyone finds them useful

Mandatory glamour shot of the finished product:

Day 2 of my 2022’s

Join 100DaysToOffload


5 responses to “Making another split keyboard: Lily58 QMK edition”

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Proud member of the 512kb club, blue team