qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

squeezing_avr.md (8339B)


      1 # Squeezing the most out of AVR
      2 
      3 AVR is severely resource-constrained, and as QMK continues to grow, it is approaching a point where support for AVR may need to be moved to legacy status as newer development is unable to fit into those constraints.
      4 
      5 However, if you need to reduce the compiled size of your firmware to fit the controller's limited flash size, there are a number of options to do so.
      6 
      7 ## `rules.mk` Settings
      8 First and foremost is enabling link time optimization. To do so, add this to your rules.mk:
      9 ```make
     10 LTO_ENABLE = yes
     11 ```
     12 This will cause the final step to take longer, but should get you a smaller compiled size. This also disables Action Functions, and Action Macros, both of which are deprecated.
     13 This will get you the most savings, in most situations.
     14 
     15 From there, disabling extraneous systems will help -- e.g.:
     16 ```make
     17 CONSOLE_ENABLE = no
     18 COMMAND_ENABLE = no
     19 MOUSEKEY_ENABLE = no
     20 EXTRAKEY_ENABLE = no
     21 ```
     22 This disables some of the functionality that you may not need. But note that extrakeys disables stuff like the media keys and system volume control.
     23 
     24 If that isn't enough to get your firmware down to size, then there are some additional features that you can disable:
     25 ```make
     26 SPACE_CADET_ENABLE = no
     27 GRAVE_ESC_ENABLE = no
     28 MAGIC_ENABLE = no
     29 ```
     30 These features are enabled by default, but they may not be needed. Double check to make sure. The [Magic Keycodes](keycodes_magic) are the largest and control things like NKRO toggling, GUI and ALT/CTRL swapping, etc. Disabling them will disable those functions. See [Magic Functions](#magic-functions) for disabling related functions.
     31 
     32 If you use `sprintf` or `snprintf` functions you can save around ~400 Bytes by enabling this option.
     33 ```make
     34 AVR_USE_MINIMAL_PRINTF = yes
     35 ```
     36 
     37 This will include smaller implementations from AVRs libc into your Firmware. They are [not fully featured](https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#gaa3b98c0d17b35642c0f3e4649092b9f1), for instance zero padding and field width specifiers are not supported. So if you use `sprintf` or `snprintf` like this:
     38 ```c
     39 sprintf(wpm_str, "%03d", get_current_wpm());
     40 snprintf(keylog_str, sizeof(keylog_str), "%dx%d, k%2d : %c");
     41 ```
     42 
     43 you will still need the standard implementation.
     44 
     45 ## `config.h` Settings
     46 
     47 If you've done all of that, and you don't want to disable features like RGB, Audio, OLEDs, etc, there are some additional options that you can add to your config.h that can help.
     48 
     49 Starting with Lock Key support. If you have a Cherry MX Lock switch (lucky you!), you don't want to do this. But chances are, you don't. In that case, add this to your `config.h`:
     50 ```c
     51 #undef LOCKING_SUPPORT_ENABLE
     52 #undef LOCKING_RESYNC_ENABLE
     53 ```
     54 Oneshots. If you're not using these, you can disable the feature by adding this to your `config.h`:
     55 ```c
     56 #define NO_ACTION_ONESHOT
     57 ```
     58 The same with tapping keys (mod tap, layer tap, etc)
     59 ```c
     60 #define NO_ACTION_TAPPING
     61 ```
     62 ## Audio Settings
     63 
     64 If you're using the Audio feature, by default that includes the music mode feature. This translates matrix positions into notes. It's neat for sure, but most likely, you're not using it. You can disable it by adding this to your `config.h`:
     65 ```c
     66 #define NO_MUSIC_MODE
     67 ```
     68 And by adding this to your `rules.mk`
     69 ```make
     70 MUSIC_ENABLE = no
     71 ```
     72 
     73 ## Layers
     74 
     75 There are also some options for layers, that can reduce the firmware size. All of these settings are for your `config.h`.
     76 
     77 You can limit the number of layers that the firmware uses -- if you're using up to 8 layers in total:
     78 ```c
     79 #define LAYER_STATE_8BIT
     80 ```
     81 or if you require up to 16 layers instead:
     82 ```c
     83 #define LAYER_STATE_16BIT
     84 ```
     85 Or if you're not using layers at all, you can outright remove the functionality altogether:
     86 ```c
     87 #define NO_ACTION_LAYER
     88 ```
     89 
     90 ## OLED tweaks
     91 
     92 One place you can save a bunch of space here is by not using `sprintf` or `snprintf`. This function call takes up ~1.5kB of firmware space, and can be rewritten. For instance, WPM uses this a lot.
     93 
     94 You can convert this:
     95 ```c
     96     // OLD CODE
     97     char wpm_str[4] = {0};
     98     sprintf(wpm_str, "WPM: %03d", get_current_wpm());
     99     oled_write(wpm_str, ' '), false);
    100 ```
    101 into this:
    102 ```c
    103     // NEW CODE
    104     oled_write_P(PSTR("WPM: "), false);
    105     oled_write(get_u8_str(get_current_wpm(), ' '), false);
    106 ```
    107 which outputs `WPM:   5`. Or this:
    108 ```c
    109     // NEW CODE
    110     oled_write_P(PSTR("WPM: "), false);
    111     oled_write(get_u8_str(get_current_wpm(), '0'), false);
    112 ```
    113 which outputs `WPM: 005`.
    114 
    115 ## RGB Settings
    116 
    117 If you're using RGB on your board, both RGB Light (Underglow) and RGB Matrix (per key RGB) now require defines to enable different animations -- some keyboards enable a lot of animations by default, so you can generally gain back some space by disabling specific animations if you don't use them. For RGB Light you can disable these in your keymap's `config.h`:
    118 ```c
    119 #undef RGBLIGHT_ANIMATIONS
    120 #undef RGBLIGHT_EFFECT_BREATHING
    121 #undef RGBLIGHT_EFFECT_RAINBOW_MOOD
    122 #undef RGBLIGHT_EFFECT_RAINBOW_SWIRL
    123 #undef RGBLIGHT_EFFECT_SNAKE
    124 #undef RGBLIGHT_EFFECT_KNIGHT
    125 #undef RGBLIGHT_EFFECT_CHRISTMAS
    126 #undef RGBLIGHT_EFFECT_STATIC_GRADIENT
    127 #undef RGBLIGHT_EFFECT_RGB_TEST
    128 #undef RGBLIGHT_EFFECT_ALTERNATING
    129 #undef RGBLIGHT_EFFECT_TWINKLE
    130 ```
    131 
    132 For RGB Matrix, these need to be explicitly enabled as well. To disable any that were enabled by the keyboard, add one or more of these to your keymap's `config.h`:
    133 ```c
    134 #undef ENABLE_RGB_MATRIX_ALPHAS_MODS
    135 #undef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
    136 #undef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
    137 #undef ENABLE_RGB_MATRIX_BREATHING
    138 #undef ENABLE_RGB_MATRIX_BAND_SAT
    139 #undef ENABLE_RGB_MATRIX_BAND_VAL
    140 #undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
    141 #undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
    142 #undef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
    143 #undef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
    144 #undef ENABLE_RGB_MATRIX_CYCLE_ALL
    145 #undef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
    146 #undef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
    147 #undef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
    148 #undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN
    149 #undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
    150 #undef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
    151 #undef ENABLE_RGB_MATRIX_CYCLE_SPIRAL
    152 #undef ENABLE_RGB_MATRIX_DUAL_BEACON
    153 #undef ENABLE_RGB_MATRIX_RAINBOW_BEACON
    154 #undef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
    155 #undef ENABLE_RGB_MATRIX_FLOWER_BLOOMING
    156 #undef ENABLE_RGB_MATRIX_RAINDROPS
    157 #undef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
    158 #undef ENABLE_RGB_MATRIX_HUE_BREATHING
    159 #undef ENABLE_RGB_MATRIX_HUE_PENDULUM
    160 #undef ENABLE_RGB_MATRIX_HUE_WAVE
    161 #undef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
    162 #undef ENABLE_RGB_MATRIX_PIXEL_FLOW
    163 #undef ENABLE_RGB_MATRIX_PIXEL_RAIN
    164 
    165 #undef ENABLE_RGB_MATRIX_TYPING_HEATMAP
    166 #undef ENABLE_RGB_MATRIX_DIGITAL_RAIN
    167 
    168 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
    169 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE
    170 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
    171 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
    172 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
    173 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
    174 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
    175 #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
    176 #undef ENABLE_RGB_MATRIX_SPLASH
    177 #undef ENABLE_RGB_MATRIX_MULTISPLASH
    178 #undef ENABLE_RGB_MATRIX_SOLID_SPLASH
    179 #undef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
    180 ```
    181 
    182 # Final Thoughts
    183 
    184 If you've done all of this, and your firmware is still too large, then it is time to consider making the switch to ARM. There are a number of Pro Micro replacements with an ARM controller:
    185 * [Bonsai C](https://github.com/customMK/Bonsai-C) (Open Source, DIY/PCBA)
    186 * [STeMCell](https://github.com/megamind4089/STeMCell) (Open Source, DIY/PCBA)
    187 * [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040)
    188 * [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288)
    189 * [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622)
    190 * [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040)
    191 * [0xCB Helios](https://keeb.supply/products/0xcb-helios) ([Open Source](https://github.com/0xCB-dev/0xCB-Helios), DIY/PCBA/Shop)
    192 * [Liatris](https://splitkb.com/products/liatris)
    193 * [Imera](https://splitkb.com/products/imera)
    194 * [Michi](https://github.com/ci-bus/michi-promicro-rp2040)
    195 * [Proton C](https://qmk.fm/proton-c/) (out of stock)
    196 
    197 There are other, non-Pro Micro compatible boards out there. The most popular being:
    198 * [WeAct Blackpill F411](https://www.aliexpress.com/item/1005001456186625.html) (~$6 USD)