Make XON/XOFF flow control actually work. Still disabled by default.
This commit is contained in:
parent
b2e1cfd8b5
commit
8b5e21be51
12
dda_queue.c
12
dda_queue.c
|
|
@ -21,6 +21,10 @@ uint8_t queue_empty() {
|
|||
return ((mb_tail == mb_head) && (movebuffer[mb_tail].live == 0))?255:0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// This is the one function called by the timer interrupt.
|
||||
// It calls a few other functions, though.
|
||||
// -------------------------------------------------------
|
||||
void queue_step() {
|
||||
disableTimerInterrupt();
|
||||
|
||||
|
|
@ -71,8 +75,9 @@ void enqueue(TARGET *t) {
|
|||
mb_head = h;
|
||||
|
||||
#ifdef XONXOFF
|
||||
// if queue is full, stop transmission
|
||||
if (queue_full())
|
||||
// If the queue has only two slots remaining, stop transmission. More
|
||||
// characters might come in until the stop takes effect.
|
||||
if (((mb_tail - mb_head - 1) & (MOVEBUFFER_SIZE - 1)) < (MOVEBUFFER_SIZE - 2))
|
||||
xoff();
|
||||
#endif
|
||||
|
||||
|
|
@ -105,8 +110,7 @@ void enqueue_temp_wait() {
|
|||
mb_head = h;
|
||||
|
||||
#ifdef XONXOFF
|
||||
// if queue is full, stop transmission
|
||||
if (queue_full())
|
||||
if (((mb_tail - mb_head - 1) & (MOVEBUFFER_SIZE - 1)) < (MOVEBUFFER_SIZE - 2))
|
||||
xoff();
|
||||
#endif
|
||||
|
||||
|
|
|
|||
24
serial.c
24
serial.c
|
|
@ -48,8 +48,7 @@ volatile uint8_t txbuf[BUFSIZE];
|
|||
#ifdef XONXOFF
|
||||
#define FLOWFLAG_SEND_XON 1
|
||||
#define FLOWFLAG_SEND_XOFF 2
|
||||
#define FLOWFLAG_SENT_XON 4
|
||||
#define FLOWFLAG_SENT_XOFF 8
|
||||
#define FLOWFLAG_STATE_XON 4
|
||||
// initially, send an XON
|
||||
volatile uint8_t flowflags = FLOWFLAG_SEND_XON;
|
||||
#endif
|
||||
|
|
@ -88,11 +87,11 @@ ISR(USART_UDRE_vect)
|
|||
#ifdef XONXOFF
|
||||
if (flowflags & FLOWFLAG_SEND_XON) {
|
||||
UDR0 = ASCII_XON;
|
||||
flowflags = (flowflags & ~FLOWFLAG_SEND_XON) | FLOWFLAG_SENT_XON;
|
||||
flowflags = FLOWFLAG_STATE_XON;
|
||||
}
|
||||
else if (flowflags & FLOWFLAG_SEND_XOFF) {
|
||||
UDR0 = ASCII_XOFF;
|
||||
flowflags = (flowflags & ~FLOWFLAG_SEND_XOFF) | FLOWFLAG_SENT_XOFF;
|
||||
flowflags = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
@ -193,15 +192,26 @@ void serial_writestr_P(PGM_P data)
|
|||
|
||||
#ifdef XONXOFF
|
||||
void xon() {
|
||||
if (flowflags & FLOWFLAG_SENT_XOFF)
|
||||
// disable TX interrupt
|
||||
UCSR0B &= ~MASK(UDRIE0);
|
||||
|
||||
if ((flowflags & FLOWFLAG_STATE_XON) == 0)
|
||||
flowflags = FLOWFLAG_SEND_XON;
|
||||
else
|
||||
flowflags = FLOWFLAG_STATE_XON; // purge a possible FLOWFLAG_SEND_XOFF
|
||||
|
||||
// enable TX interrupt so we can send this character
|
||||
UCSR0B |= MASK(UDRIE0);
|
||||
}
|
||||
|
||||
void xoff() {
|
||||
flowflags = FLOWFLAG_SEND_XOFF;
|
||||
// enable TX interrupt so we can send this character
|
||||
UCSR0B &= ~MASK(UDRIE0);
|
||||
|
||||
if (flowflags & FLOWFLAG_STATE_XON)
|
||||
flowflags = FLOWFLAG_SEND_XOFF | FLOWFLAG_STATE_XON;
|
||||
else
|
||||
flowflags = 0;
|
||||
|
||||
UCSR0B |= MASK(UDRIE0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue