|
@@ -25,7 +25,7 @@ static uint8_t parity;
|
|
|
*/
|
|
|
ISR(USART1_UDRE_vect)
|
|
|
{
|
|
|
- static uint8_t data, left;
|
|
|
+ static uint8_t data, left, gap;
|
|
|
uint8_t pattern;
|
|
|
|
|
|
if (!left) {
|
|
@@ -34,28 +34,31 @@ ISR(USART1_UDRE_vect)
|
|
|
nd = motor_relay ? fmtx_next_byte() : -1;
|
|
|
if (nd < 0) {
|
|
|
/*
|
|
|
- * Nothing to send. Disable the interrupt and
|
|
|
- * send out one last edge. Afterwards, the hardware
|
|
|
- * will drive the line high.
|
|
|
+ * Nothing to send. Hold the line for some
|
|
|
+ * number of byte-times in case we suffered an
|
|
|
+ * underrun. Afterwards, the hardware will
|
|
|
+ * drive the line high.
|
|
|
*/
|
|
|
- fmtx_disable();
|
|
|
-
|
|
|
- UCSR1A = TX_IDLE;
|
|
|
- UDR1 = parity; /* One last edge before going high */
|
|
|
- parity = 0;
|
|
|
+ if (++gap) {
|
|
|
+ UCSR1A = TX_IDLE;
|
|
|
+ UCSR1A = parity;
|
|
|
+ } else {
|
|
|
+ fmtx_disable();
|
|
|
+ }
|
|
|
return;
|
|
|
}
|
|
|
data = nd;
|
|
|
left = 8;
|
|
|
+ gap = 0;
|
|
|
}
|
|
|
|
|
|
- pattern = fm_pat[data & PATTERN_BIT_MASK] ^ ~parity;
|
|
|
+ pattern = fm_pat[data & PATTERN_BIT_MASK] ^ parity;
|
|
|
|
|
|
UCSR1A = TX_IDLE;
|
|
|
UDR1 = pattern;
|
|
|
data >>= BITS_PER_PATTERN_BYTE;
|
|
|
left -= BITS_PER_PATTERN_BYTE;
|
|
|
- parity = -((int8_t)pattern >= 0);
|
|
|
+ parity = -((int8_t)pattern < 0);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -91,7 +94,7 @@ uint32_t fmtx_real_baudrate(uint32_t baudrate)
|
|
|
|
|
|
void fmtx_init_speed(uint32_t baudrate)
|
|
|
{
|
|
|
- parity = 0; /* We start out with a high idle */
|
|
|
+ parity = 0xff; /* We start out with a high idle */
|
|
|
|
|
|
UCSR1B = 0; /* Disable transmitter and ISR */
|
|
|
UCSR1A = (1 << TXC1); /* Clear TXC bit */
|