Idea: Remove the USB stack and regain 3,000 bytes of Flash

After struggeling with inline assembly and the compiler I finally managed to squeeze out 74 more bytes out of micros() and delay() functions in wiring.c It has the Bootloader + Reset buttons feature and 118 more free bytes as a bonus :smiley: ( @JayGarcia I made a pull request for Evade 2 )

I forgot to mention before that I also added button support for the DevKit. When building for devkit you’ll have 4 less bytes due to the different button implementation.

I’ve also added it to my board package with options Arduboy/Arduboy Safe and Arduboy no USB) and works like a treat. Just need to update my adapted Arduboy 2 library before a release. @MLXXXp are you planning any updates to Arduboy2 master soon?

1 Like

Hard core. :slight_smile: That’s impressive.

1 Like

I’ve been a bit busy during the holiday season but I’d like to get a new release out soon, with at least the unreleased changes/fixes in the master branch, and also @Pharap’s refactored drawCompressed() PR #19, if my testing doesn’t show any problems.

I was also hoping to look at your PR #17 to see if there are any optimisations that would apply, while still only supporting official Arduboy hardware.

I’m still not sure about including USB stack removal functions.


You’ll sure want to copy my buttonsState() function. It saves 42 more bytes :slight_smile:
I need to have a look at my fast display code again to see if it also saves a few bytes extra bytes besides clocking out data at a steady 18 clock cycles per byte.
Besides the extra OLED and resolution support there where a few minor ones like putting OLED chip/data/cmd selects inline. I haven’t

Here’s the optimized buttonsState. It may look much but thanks to SBIS instructions and removing the wastefull << operator, it compiles to 14 bytes.

uint8_t Arduboy2Core::buttonsState()
  uint8_t buttons;
  static uint8_t button_hold;

  // using ports here is ~100 bytes smaller than digitalRead()
#ifdef AB_DEVKIT
  // down, left, up
  buttons = ((~PINB) & B01110000);
  // right button
  if ((PINC & _BV(6)) == 0) buttons |= RIGHT_BUTTON; //using this notation compiles to shorter code
  // A and B
  if ((PINF & _BV(7)) == 0) buttons |= A_BUTTON;
  if ((PINF & _BV(6)) == 0) buttons |= B_BUTTON;
#elif defined(ARDUBOY_10)
  // up, right, left, down
  buttons = ((~PINF) & B11110000);
  // A (left)
if ((PINE & _BV(6)) == 0) {buttons |= A_BUTTON;}
  // B (right)
  if ((PINB & _BV(4)) == 0) {buttons |= B_BUTTON;}
  return buttons;

EDIT: I did a quick comparison:

  • display() originally takes 20 bytes vs mine taking 42 bytes
  • display(true) originally takes 40 bytes vs mine taking 42 bytes

I sacrificed these 22/2 bytes for a considerable speed gain. both display() and display(true) also take the same amount of time.


Hy @Mr.Blinky, I believe you created a PR for the forked repo versus a PR to pull into Evade2’s repo. :smiley: <-- Pull ID 1 :stuck_out_tongue:

Sorry. I’m not used to using github. The browser version doesn’t seem to have a synching option to synch with the master.


Hopefully I pulled the right request now :smile:


I merged the PR. Thank you for this!

1 Like

The github webpage, while brilliant for people who aren’t used to git and can’t be bothered to sit down to learn it (which is fair enough, it’s quite complex) is missing a lot of things that would come in handy.

Yes and their desktop client isn’t an option for me either as I’m running 32-bit Windows. I’m having a look at Turtuoise + git but TBH I’m not putting much time into it atm.

I now have 110 free bytes to work with. Would love to squeeze another song in :stuck_out_tongue:


I wanted to check in and say that this code has been really friggin awesome for Evade 2’s updates.

I have busted 4 Arduboys because the reset button feedback mechanism gets “soft” overtime, causing me to push harder and eventually break the button.

Thank you @Mr.Blinky for this!!

1 Like

I can also recomend to burn (one of those) busted Arduboy’s with my custom bootloader

Apart from having the breathing RGB LED as visual feedback in bootloader mode. You can keep it in bootloader mode by holding down the down button. You also get one more Kb breathing space for development. It has more features but these are most useful for development.


@MLXXXp, I just pushed
The idea is to prevent magic key overwrite by placing a variable at the absolute magic key location so the compiler will not use that location for other program’s variables storage.

If that works then it becomes possible to use the watchdog to enter the bootloader when an application hangs.


Cool! I didn’t know you could do that. Does the compiler generate an error if you claim enough ram to cross the magic key address?

The linked should “allocate around” that location. It’s already taken so it is not be used for other variables i.e. the location is not an hard limit on the available RAM.

It doesn’t seem to. I’ve posted a comment in your PR.

1 Like

PR retired, it seems the compiler does not reuse that location for .data and .bss sections but it is still liable to being overwritten by the stack. Thank you very much for testing it.

1 Like

Do note that you can reset it by turning it off then back on.
Really? Because I have carefully inspected that button under a magnifying glass, and I can tell that that thing was of a decent quality. (Make sure to press JUST ENOUGH so the contact pins snap into place, the plastic thing IS soft)

Power on Reset is not the same as having the device powered on and pressing the reset button.

1 Like

You should see my one with a flaky power switch that triggers the bootloader.