From a438a3fa2f530ac5d9beb161c5716e099b388ad5 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Tue, 5 Oct 2010 20:22:09 +0200 Subject: [PATCH] Implement XON/XOFF handling for the serial read queue. The former solution was less computing intensive, but failed when the GCode interpreter couldn't keep up with the incoming stream, e.g. when handling a lot of tiny moves. The old implementation is still in place but somewhat redundant now, so stay tuned ... Oh, and G4 Dwell works now as well. --- serial.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/serial.c b/serial.c index 9f75128..233323c 100644 --- a/serial.c +++ b/serial.c @@ -88,6 +88,15 @@ ISR(USART0_RX_vect) // not reading the character makes the interrupt logic to swamp us with retries, so better read it and throw it away trash = UDR0; } + + #ifdef XONXOFF + if (flowflags & FLOWFLAG_STATE_XON && buf_canread(rx) >= BUFSIZE - 16) { + // the buffer has only 16 free characters left, so send an XOFF + // more characters might come in until the XOFF takes effect + flowflags = FLOWFLAG_SEND_XOFF | FLOWFLAG_STATE_XON; + UCSR0B |= MASK(UDRIE0); + } + #endif } #ifdef USART_UDRE_vect @@ -125,9 +134,19 @@ uint8_t serial_rxchars() uint8_t serial_popchar() { uint8_t c = 0; + // it's imperative that we check, because if the buffer is empty and we pop, we'll go through the whole buffer again if (buf_canread(rx)) buf_pop(rx, c); + + #ifdef XONXOFF + if ((flowflags & FLOWFLAG_STATE_XON) == 0 && buf_canread(rx) <= 16) { + // the buffer has (BUFSIZE - 16) free characters again, so send an XON + flowflags = FLOWFLAG_SEND_XON; + UCSR0B |= MASK(UDRIE0); + } + #endif + return c; }