I am trying to make half duplex (over single wire) communication between ATTiny2313A and ATMega48V. I am using hardware USART on both devices. The Mega is running at 8Mhz with UBRR0=7 and Tiny at 1MHz with UBRR=0 giving 62.5kbps baud. To release the line as soon as a byte is sent I use following code:
UCSR0B|=(1<<TXEN0); UDR0=outgoingData; UCSR0B&=~(1<<TXEN0);
(or without the 0 for the Tiny). It should work because the Datasheet says:
When writing the TX Enable bit in the USART Control and Status Register n B (UCSRnB.TXEN) to zero,
the disabling of the Transmitter will not become effective until ongoing and pending transmissions are
completed, i.e., when the Transmit Shift Register and Transmit Buffer Register do not contain data to be
transmitted. When disabled, the Transmitter will no longer override the TxDn pin.
And it really works - most of the time. On the Tiny the transfer is always finished. On the Mega it sometimes shortly pulls the line low and again releases it (TX pin goes high impedance). The byte in UDR is lost and the pulse is too short to be registered as a valid start bit by either device. But sometimes (more often) it sends the byte flawlessly. Adding single "nop" between writing UDR and clearing TXEN does not prevent such behavior. But adding enough "nops" (I tried 8) helps. I think it is a flaw in USART state machine when using high enough UBRR prescaler. What cases this? Does all AVRs exhibit such behavior or is it only limited to some devices/die revisions?