Here's one for the brain trust. I've been working on it for the last three days and quite frankly I'm stumped. I believe I've lost sight of the forest, or is it the trees?
In any event, I don't want to give away any spoilers so as to not bias any opinions. For the sake of not reinventing however, I will cover some key ground that has already be tread.
This is essentially an implementation of AVR304 with a couple of twists. It uses a transmit buffer and is interrupt driven (bit-wise) so there is no blocking.
The receive portion has not been sussed out yet so look at that at your leisure, this strictly has to do with the transmit side.
A data analyzer was connected to the transmit pin so all framing has been checked and is accurate.
All testing has been done with a Uno as the master and a Mega2560 the slave. The slave is set to use one of its USARTs to receive so there is no drama there.
The master is set up with an option (called side_track) that allows for bit-banging the output, selectable at run time via #/$.
A test state exists in the interrupt routine that pumps out 1ms worth of pulses to check timing, accessible via @.
Caveats.
I do not wish to enter into any philosophical debates. I come from an old school that believes in monolithic programming and for embedded systems especially, prefer to have all my code in one place. The exercise here is to have a single file that can be compiled anywhere and uploaded without concern as to whether the correct libraries are available. The first step is to exit from the Arduino IDE and go straight to the AVR-GCC compiler.
An undocumented reality is that if you swap out the setup and loop functions for main and an endless while, all the Arduino behind-the-scenes add-ons are not added on. You will notice that these lines are commented in/out to be able to switch back and forth.
Timer2 drives the ISR, Timer0 is there to offer millis() and micros() in the timing loop but otherwise not needed. Timer1 is used for non-prescaled timing for the bit-banged alternative but otherwise it too is not needed.
Lastly, in this bit, is that the intent of this code is to provide a workable test-bed to play with non-standard data transmission, specifically 9-bit data. My intent is to post this on my Github page when it is working so feel free to pass it around now.
Issue.
With loop and setup invoked, everything works fine. If you switch over to main and while, the interrupt driven transmit only sends the first character. Whilst still in this mode, you can switch to bit-bang (#) and it works. Also, if you invoke the 1ms pulse stream (@), it works as well. There does not appear to be an issue with the interrupt handler except that it processes only the first character and only in the main/while configuration. Again, switching back to setup/loop everything works.
One might think that some Arduino add-on is missing in the main/while compilation when you look at the sketch size, 1998 in the main/loop version and 2132 for the setup/loop. So there seems to be something no there but like I said, I've been staring at it for so long now I just don't see any more. Perhaps you all can spot it?
I can't post the code as it's a touch too long so I've attached it.
bare_metal_usart_rev3a.ino (18.5 KB)