NewSoftSerial Library: An AFSoftSerial update

As long as the clock is 16MHz, I think it's a fair bet that it will work, although I haven't tested anything but the Diecimila.

I've got a few unassembled RBBBs laying around with 16mhz crystals so il put in a 328, when they arrive, and give it a spin.

Wow, you guys are amazing. Nice inline assembly fix. I'm going to upgrade the Mac AVR tools to the latest version from AVR Mac Pack (which includes avr-gcc 4.3.2).

mellis, where will you be posting them? An update to 0013 zip? Or just instructions on what to grab from another site to do surgery ourselves?

The inline assembly is cool but only works on a case-by-case basis, and there are other folks (including me) who have been bitten by the broken interrupt handlers on OSX.

@mellis, back when I was investigating the problem with the broken Ubuntu random() function, the guys on the avr-libc forum advised steering clear of the 4.3.0 avr-gcc compiler, which they characterized as "broken". I thought it was funny that that's the version we use with Windows Arduino. Perhaps it would be good to upgrade all the Arduino distros to 4.3.2?

Mikal

Good point. The latest version of WinAVR has gcc 4.3.2, too. I hope to upgrade both OSes for Arduino 0014.

I'm happy to say that I have incorporated etracer's mods to [u]NewSoftSerial[/u] and after running the Windows-compiled object through my baud rate test suite, I find that the slightly longer RX interrupt handlers do not significantly affect the error rate.

ERROR RATES
   | 300  | 1200 | 2400 | 4800 | 9600  | 14.4K | 19.2K  |  28.8K | 31.25K  | 38.4K  | 57.6K  | 115.2K
TX |  0%  |  0%  |  0%  |  0%  |  0%   |   0%  |   0%   |   0%   |   0%    |   0%   |    0%  |    0%
RX |  0%  |  0%  |  0%  |  0%  |  0%   |   0%  |   0%   |   0%   |   0%    | 0.1%   | 0.35%  |   N/A

@mellis: I would love to be able to make etracer's fix conditional on whether it is needed. This seems an excellent example of a use case that would benefit from the

#define ARDUINO_VERSION 14

proposal I made.

OSX users: Please test. And would someone please compile NSS 5 on OSX for Diecimila/Duemilanove and send me the binary? I would like to run it through my test bench.

Mikal

http://sundial.org/arduino/index.php/newsoftserial/

I'm getting a "Page not found" error when trying to download the latest version.

Ouch. Sorry. I thought I had tested all the links. Try again.

http://sundial.org/arduino/NewSoftSerial/NewSoftSerial5.zip

Mikal

And would someone please compile NSS 5 on OSX for Diecimila/Duemilanove and send me the binary? I would like to run it through my test bench.

Check your private messages.

Tonight I thoroughly tested etracer's OSX build of NewSoftSerial v5 and it performs admirably at all supported baud rates, perhaps even slightly better than the Windows build.

Thanks again, etracer, for your work.

Mikal

i fixed a small bug in the interrupt names that was giving 328's a 'compiles but freaks' problem
also made the examples folder a little neater
otherwise, works very nicely with 1 GPS module under v13 ide on windows and mac osx tested with 168 and 328p

http://www.ladyada.net/media/gpsshield/NewSoftSerial_18-02-09.zip

Thank you very much, ladyada.

Mikal

I posted NewSoftSerial 6 today, which contains ladyada's contributions. This new version supports the Atmega328p that she sells. Go buy a bunch of them.

Thanks,

Mikal

well, to be specific, it should work under any 328p
-however- the interrupt bug in v13 is not resolved so there may be freaky experiences.

Note also that the inline assembly work-around for the OSX 0013 interrupt bug that I provided may not work with the 328. I don't know if the compiler will generate the same register code as for a 168 (and I don't have any 328's to test with).

That being said, I suspect it will work because I can't see any way that the buggy 4.3.0 version of the compiler would know about the 328 and have specific optimizations.

-however- the interrupt bug in v13 is not resolved so there may be freaky experiences.

Oh, sorry, I thought you said in your previous post that you had tested NSS5 with etracer's workaround on the 328p... ?

otherwise, works very nicely with 1 GPS module under v13 ide on windows and mac osx tested with 168 and 328p

Is this not correct?

M

the 'hack' etracer added will resolve it as long as those are the registers used. the compiler can pick nearly any registers so in some cases it will still break.

the bug in v13 really needs to be fixed for NSS (and nearly any arduino code with interrupts) to work perfectly all the time
ive poked dmellis about it but hes probably quite busy & i didn't get a date for when it will be fixed :frowning:

Since this OSX avr-gcc interrupt bug is killing me on a number of projects, I got impatient and hacked in avr-gcc 4.3.2 into my OSX Arduino-0013 install. I can report that the new version fixes the interrupt bug. One minor thing I noticed is that my small test program was a little larger with avr-gcc 4.3.2. Overall it was 130 bytes larger or about 3%. This may not be significant as I'm not sure my hacked install has all of the same compile options as the "official" Arduino version will.

Also note that the corrected interrupt vector names that ladyada fixed in the latest version are critical for avr-gcc 4.3.2. With the old vector names the code would compile, but the chip would reset whenever an interrupt occurred. So there's nothing to fix as code is now correct, but it's just something to be aware of.

@mikalhart: I added some conditional compiling based on avr-gcc version so that the inline assembly hacks would only be included if needed (for 4.3.0). I'll PM you with a link, but here's the gist of the changes:

In NewSoftSerial.h, define GCC_VERSION

#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif

For avr-gcc 4.3.0, GCC_VERSION will be 40300 (40302 for 4.3.2, etc.)

In NewSoftSerial.cpp, put conditional compilation around the inline assembly so that it's only included for version 4.3.0 (the only version to be included with the IDE that has the bug). I also updated the comment to indicate 4.3.0 instead of only 4.3.

// Work-around for avr-gcc 4.3.0 OSX version bug
// Preserve the registers that the compiler misses
// (courtesy of Arduino forum user *etracer*)
#if (GCC_VERSION == 40300)
  asm volatile(
      "push r18 \n\t"
      "push r19 \n\t"
      "push r20 \n\t"
      "push r21 \n\t"
      "push r22 \n\t"
      "push r23 \n\t"
      "push r26 \n\t"
      "push r27 \n\t"
      ::);
#endif

and

// Work-around for avr-gcc 4.3.0 OSX version bug
// Restore the registers that the compiler misses
#if (GCC_VERSION == 40300)
  asm volatile(
      "pop r27 \n\t"
      "pop r26 \n\t"
      "pop r23 \n\t"
      "pop r22 \n\t"
      "pop r21 \n\t"
      "pop r20 \n\t"
      "pop r19 \n\t"
      "pop r18 \n\t"
      ::);
#endif

On a non-interrupt-bug note...

I might suggest changing your versioning scheme. It's kind of confusing to have NewSoftSerial1, NewSoftSerial2, etc. This scheme implies a major version change that added new features or fuctionality. The common versioning scheme is to use a major version number (probably 1 in this case), a minor revision (maybe 1 or 2?), and a patch level (maybe 5 or 6?).

Lastly, it would be helpful to change how you package each version. Having the directory named "NewSoftSerial6" will cause confusion for new users that are unaware that they should remove the 6 before putting it in their library directory. Then when NewSoftSerial7 comes along and they copy that, they'll get all kinds of compile errors due to the duplicate source files.

I would suggest something like this:

NewSoftSerial-1_2_3
-- NewSoftSerial
---- Examples
---- NewSoftSerial.cpp
---- NewSoftSerial.h

Then when the users expand NewSoftSerial-1_2_3.zip they can directly copy the enclosed NewSoftSerial directory to their libraries.

@etracer--

Thanks for testing with 4.3.2. I had already implemented the conditional compilation of the workaround, using GNUC_PATCHLEVEL etc., but was just waiting for confirmation that the new compiler actually did fix the problem before rolling it out.

Your point about the organization of the ZIP file is a good one. I should have thought of that. I'll certainly release the next version of NSS in that format. I probably will stick with the single-digit versioning, though. I don't think that NewSoftSerial is a big enough project to warrant an x.y.z versioning scheme, and I would have to change the NewSoftSerial::library_version() interface to support it.

Thanks much! Nice work as always.

Mikal