ATtiny Software Serial
ATtiny software serial transmit and receive, based the Arduino SoftwareSerial library, and around 1K compiled. That's what I've been working on. Why?
|Spy photo :) of ultra compact eeZeeISP AVR programmer|
Here are the details on TinySoftSerial.
OverviewThe current Arduino SoftwareSerial library is based on the NewSoftSerial library by Mikal Hart. A few years ago, NewSoftSerial was a dramatic improvement over then-incumbent SoftwareSerial, which is why the new code is part of the Arduino 1.0.x distribution.
Multiple serial listeners are supported at baud rates from 300 to 115200 though errors above 38400 at 16MHz may be too high and lower rates too slow. Overall, it's a really neat library for typical communications of 9600 - 38400.
So you may see why, when I needed serial receive (the hard part), I didn't really feel like reinventing the wheel. I need the library for other projects, too. But I needed something small and with only one software serial instance.
What I Did
- Converted to C
- Removed multiple instance capability
- Converted to native PORTx/PINx/DDRx register references
- Hardcoded to use PA0 for RX and PA1 for TX
- Shaved a few bytes here and there,
- e.g., using a mask instead of modulo for circular buffer**
- Adapted interrupt register references to ATTiny84A: GIMSK, PCMSK0
- Hardcoded 16MHz timings (for now; I may restore the other frequencies later)
- Fixed "Error: register r24, r26, r28 or r30 required" - details
- A few other things I can't remember
avr-size --format=berkeley -t TinySoftSerial.elf text data bss dec hex filename 1008 2 204 1214 4be TinySoftSerial.elf 1008 2 204 1214 4be (TOTALS) Finished building: sizedummy
** If you're curious about using a mask instead of modulo. Let's say you have a buffer of 64 bytes (or any number 2n), aka 0x40 or 26. Indexes range from 0x00 to 0x3f or 000000 to 111111. After you increment your index, simply AND it with 0x3f (2n-1). Suppose the index is 0x3f, the maximum and you increment it to 0x40. Now AND with 0x3f and you get 0x00 (%01000000 & 111111) . This is faster and uses fewer assembly instructions to implement than modulo or an if statement. Here's what it looks like in C:
#define MAXBUF 64
#define BUFMASK (MAXBUF-1)
i = (i+1) & BUFMASK;
The CodeI bet you just want the code. Ok, here it is.
Porting to ATtiny85, Etc.It shouldn't be too hard to port this to ATtiny85. You could port to ATtiny2313 although it has hardware serial separate from the USI. The library is too big for ATtiny13 to do anything useful. I don't use any other ATtinys but basically anything that has 2K flash or higher should be a go.
|Saleae Logic Analyzer: STK500 V2 protocol|