arduino/Arduino — pull request #2032 by matthijskooijman (2014-04-24 12:22:06+00:00)
Title: SoftwareSerial improvements, fixes and optimizations

This pullrequest contains a bit of everything, for the SoftwareSerial library. The first couple of commits I still had lying around from last year, forgot to send a pullrequest for those earlier. They're mostly cleanups around the introduction of a `stopListening()` method, that can be made to disable RX of a SoftwareSerial instance.

The second half of the commits are a lot of optimizations and fixes, to make the SoftwareSerial code faster and more reliable, so it works again at higher baudrates. This is only partly succesful for RX, since at higher baudrates where bytes are sent back-to-back, the CPU spends most of the time in the interrupt handler. At higher baudrates, the interrupt overhead (cleanup and setup) becomes longer than than the available time (from halfway the stopbit to halfway the startbit) and reception starts to fail.

This problem is particularly evident when running at 8Mhz, or when using gcc 4.3.2 (which makes terrible register allocation choices). Using gcc 4.8.2 and running at 16Mhz, things work up to 115200 (though bytes are still regularly corrupted because of the millis() timer ISR delaying the SoftwareSerial interrupt). Using 1.5 or 2 stop bits on the other side will probably help here (though I haven't tested this, and there is no way to make SoftwareSerial do TX with longer stop bits.

There is probably some room for improvment still, but that would require the RX ISR / `recv` method to be handcoded in assembly. The upside of that would be that it's 100% deterministic, without depending on the compiler used, but it's a lot of work that I'm not going to invest right now (getting this far has cost me enough time already).

These commits also remove the delay lookup tables that were previously present, since the values can easily be calculated at runtime. This saves around 160 bytes of program memory.

In addition to making the code faster, it is also a lot smaller. Overall, a typical SoftwareSerial sketch on the Uno saves slightly over 400 bytes of program space (including the savings for the lookup table removal).