aboutsummaryrefslogtreecommitdiff
path: root/libraries/SoftwareSerial/SoftwareSerial.h
AgeCommit message (Collapse)Author
2015-01-26Fix SoftwareSerial timingsMatthijs Kooijman
Instead of using a lookup table with (wrong) timings, this calculates the timings in SoftwareSerial::begin. This is probably a bit slower, but since it typically happens once, this shouldn't be a problem. Additionally, since the lookup tables can be removed, this is also a lot smaller, as well as supporting arbitrary CPU speeds and baudrates, instead of the limited set that was defined before. Furthermore, this switches to use the _delay_loop_2 function from avr-libc instead of a handcoded delay function. The avr-libc function only takes two instructions, as opposed to four instructions for the old one. The compiler also inlines the avr-libc function, which makes the timings more reliable. The calculated timings directly rely on the instructions generated by the compiler, since a significant amount of time is spent processing (compared to the delays, especially at higher speeds). This means that if the code is changed, or a different compiler is used, the calculations might need changing (though a few cycles more or less shouldn't cause immediate breakage). The timings in the code have been calculated from the assembly generated by gcc 4.8.2 and gcc 4.3.2. The RX baudrates supported by SoftwareSerial are still not unlimited. At 16Mhz, using gcc 4.8.2, everything up to 115200 works. At 8Mhz, it works up to 57600. Using gcc 4.3.2, it also works up to 57600 at 16Mhz and up to 38400 at 8Mhz. Note that at these highest speeds, communication works, but is still quite sensitive to other interrupts (like the millis() interrupts) when bytes are sent back-to-back, so there still are corrupted bytes in RX. TX works up to 115200 for all combinations of compiler and clock rates. This fixes #2019
2015-01-26Disable the RX PCINT inside SoftwareSerial::recvMatthijs Kooijman
Before, the interrupt would remain enabled during reception, which would re-set the PCINT flag because of the level changes inside the received byte. Because interrupts are globally disabled, this would not immediately trigger an interrupt, but the flag would be remembered to trigger another PCINT interrupt immediately after the first one is processed. Typically this was not a problem, because the second interrupt would see the stop bit, or an idle line, and decide that the interrupt triggered for someone else. However, at high baud rates, this could cause the next interrupt for the real start bit to be delayed so much that the byte got corrupted. By clearing the interrupt mask bit for just the RX pin (as opposed to the PCINT mask bit for the entire port), any PCINT events on other bits can still set the PCINT flag and be processed as normal. In this case, it's likely that there will be corruption, but that's inevitable when (other) interrupts happen during SoftwareSerial reception.
2015-01-26Optimize SoftwareSerial::setRxIntMsk()Matthijs Kooijman
This precalculates the mask register and value, making setRxIntMask considerably less complicated. Right now, this is not a big deal, but simplifying it allows using it inside the ISR next.
2015-01-26Mark SoftwareSerial::recv and handle_interrupt as always_inlineMatthijs Kooijman
Since those functions are only called once now, it makes sense to inline them. This saves a few bytes of program space, but also saves a few cycles in the critical RX path.
2015-01-26Mark SoftwareSerial::tx_pin_write as "always_inline"Matthijs Kooijman
Somehow gcc 4.8 doesn't inline this function, even though it is always called with constant arguments and can be reduced to just a few instructions when inlined. Adding the always_inline attribute makes gcc inline it, saving 46 bytes on the Arduino uno. gcc 4.3 already inlined this function, so there are no space savings there.
2015-01-26Fix race condition in SoftwareSerial::overflow()Matthijs Kooijman
If an interrupt causing overflow would occur between reading _buffer_overflow and clearing it, this overflow condition would be immediately cleared and never be returned by overflow(). By only clearing the overflow flag if an overflow actually occurred, this problem goes away (worst case overflow() returns false even though an overflow _just_ occurred, but then the next call to overflow() will return true).
2015-01-26Add SoftwareSerial::stopListening()Matthijs Kooijman
This allows one to explicitly stop a SoftwareSerial instance from listening, without having to make another one listening.
2015-01-26Add SoftwareSerial::setRxIntMsk()Matthijs Kooijman
This moves the interrupt mask enabling / disabling code into a separate method, so we can call it from multiple spots next.
2013-11-15Revert "SoftwareSerial library to the new format"Cristian Maglie
This reverts commit 38c3bbbd3c83eda057d4857635fbd78a4785c3a4.
2013-07-03SoftwareSerial library to the new formatFede85
2012-12-10fixed permissions on a lot of text files. see #1116Federico Fissore
2012-01-04Moved libraries folder inside platform folder. Now libraries and examples ↵Cristian Maglie
are searched per board/platform
2009-11-07Moving libraries out of arduino platform / core directory and to top-level.David A. Mellis
2007-10-06Moving libraries out from inside targets and creating bootloaders directory.David A. Mellis