Minor include related compile fix. Added experimental XON/XOFF flow control. Not officially supported!
- A latency issue related to USB-to-serial converters on the Arduino does not allow for XON/XOFF flow control to work correctly on standard terminal programs. It seems that only specialized UI's or avoiding the USB port all together solves this problem. However, XON/XOFF flow control is added for advanced users only as a compile-time option. This feature is officially *NOT* supported by grbl, but let us know of any successes with it!
This commit is contained in:
parent
e9b28279db
commit
d6abf10d49
8
config.h
8
config.h
@ -114,6 +114,14 @@
|
||||
// time step. Also, keep in mind that the Arduino delay timer is not very accurate for long delays.
|
||||
#define DWELL_TIME_STEP 50 // Integer (1-255) (milliseconds)
|
||||
|
||||
// FOR ADVANCED USERS ONLY: Toggles XON/XOFF software flow control for serial communications.
|
||||
// Officially not supported due to problems involving USB-to-serial chip latency (Atmega8U2/FTDI)
|
||||
// when connecting to an Arduino through the USB port. This problem has to do with having no control
|
||||
// of the USB packets and causing standard terminal programs not being able to honor the XON/XOFF
|
||||
// control characters on time. However, with specially programmed UI's or avoiding the USB interface
|
||||
// completely, XON/XOFF flow control should work. In any case, please report any successes to grbl
|
||||
// administrators!
|
||||
#define ENABLE_XONXOFF 0 // Boolean. Default disabled.
|
||||
|
||||
// -----------------------------------------------
|
||||
|
||||
|
@ -21,10 +21,11 @@
|
||||
|
||||
#ifndef nuts_bolts_h
|
||||
#define nuts_bolts_h
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "config.h"
|
||||
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
73
serial.c
73
serial.c
@ -42,6 +42,27 @@ uint8_t tx_buffer[TX_BUFFER_SIZE];
|
||||
uint8_t tx_buffer_head = 0;
|
||||
volatile uint8_t tx_buffer_tail = 0;
|
||||
|
||||
#if ENABLE_XONXOFF
|
||||
#define RX_BUFFER_FULL 96 // XOFF high watermark
|
||||
#define RX_BUFFER_LOW 64 // XON low watermark
|
||||
#define SEND_XOFF 1
|
||||
#define SEND_XON 2
|
||||
#define XOFF_SENT 3
|
||||
#define XON_SENT 4
|
||||
#define XOFF_CHAR 0x13
|
||||
#define XON_CHAR 0x11
|
||||
volatile uint8_t flow_ctrl = XON_SENT; // Flow control state variable
|
||||
|
||||
// Returns the number of bytes in the RX buffer. This replaces a typical byte counter to prevent
|
||||
// the interrupt and main programs from writing to the counter at the same time.
|
||||
static uint8_t get_rx_buffer_count()
|
||||
{
|
||||
if (rx_buffer_head == rx_buffer_tail) { return(0); }
|
||||
if (rx_buffer_head < rx_buffer_tail) { return(rx_buffer_tail-rx_buffer_head); }
|
||||
return (RX_BUFFER_SIZE - (rx_buffer_head-rx_buffer_tail));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void set_baud_rate(long baud) {
|
||||
uint16_t UBRR0_value = ((F_CPU / 16 + baud / 2) / baud - 1);
|
||||
UBRR0H = UBRR0_value >> 8;
|
||||
@ -84,21 +105,33 @@ void serial_write(uint8_t data) {
|
||||
}
|
||||
|
||||
// Data Register Empty Interrupt handler
|
||||
ISR(USART_UDRE_vect) {
|
||||
ISR(USART_UDRE_vect)
|
||||
{
|
||||
// Temporary tx_buffer_tail (to optimize for volatile)
|
||||
uint8_t tail = tx_buffer_tail;
|
||||
|
||||
#if ENABLE_XONXOFF
|
||||
switch (flow_ctrl) {
|
||||
case SEND_XOFF: UDR0 = XOFF_CHAR; flow_ctrl = XOFF_SENT; break;
|
||||
case SEND_XON: UDR0 = XON_CHAR; flow_ctrl = XON_SENT; break;
|
||||
default:
|
||||
#endif
|
||||
|
||||
// Send a byte from the buffer
|
||||
UDR0 = tx_buffer[tail];
|
||||
|
||||
// Update tail position
|
||||
tail ++;
|
||||
tail++;
|
||||
if (tail == TX_BUFFER_SIZE) { tail = 0; }
|
||||
|
||||
tx_buffer_tail = tail;
|
||||
|
||||
#if ENABLE_XONXOFF
|
||||
}
|
||||
#endif
|
||||
|
||||
// Turn off Data Register Empty Interrupt to stop tx-streaming if this concludes the transfer
|
||||
if (tail == tx_buffer_head) { UCSR0B &= ~(1 << UDRIE0); }
|
||||
|
||||
tx_buffer_tail = tail;
|
||||
}
|
||||
|
||||
uint8_t serial_read()
|
||||
@ -109,6 +142,14 @@ uint8_t serial_read()
|
||||
uint8_t data = rx_buffer[rx_buffer_tail];
|
||||
rx_buffer_tail++;
|
||||
if (rx_buffer_tail == RX_BUFFER_SIZE) { rx_buffer_tail = 0; }
|
||||
|
||||
#if ENABLE_XONXOFF
|
||||
if ((get_rx_buffer_count() < RX_BUFFER_LOW) && flow_ctrl != XON_SENT) {
|
||||
flow_ctrl = SEND_XON;
|
||||
UCSR0B |= (1 << UDRIE0); // Force TX
|
||||
}
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -116,11 +157,8 @@ uint8_t serial_read()
|
||||
ISR(USART_RX_vect)
|
||||
{
|
||||
uint8_t data = UDR0;
|
||||
uint8_t next_head = rx_buffer_head + 1;
|
||||
if (next_head == RX_BUFFER_SIZE) { next_head = 0; }
|
||||
uint8_t next_head;
|
||||
|
||||
// Write data to buffer unless it is full.
|
||||
if (next_head != rx_buffer_tail) {
|
||||
// Pick off runtime command characters directly from the serial stream. These characters are
|
||||
// not passed into the buffer, but these set system state flag bits for runtime execution.
|
||||
switch (data) {
|
||||
@ -135,9 +173,22 @@ ISR(USART_RX_vect)
|
||||
}
|
||||
sys.execute |= EXEC_RESET; // Set as true
|
||||
break;
|
||||
default : // Write character to buffer
|
||||
default: // Write character to buffer
|
||||
next_head = rx_buffer_head + 1;
|
||||
if (next_head == RX_BUFFER_SIZE) { next_head = 0; }
|
||||
|
||||
// Write data to buffer unless it is full.
|
||||
if (next_head != rx_buffer_tail) {
|
||||
rx_buffer[rx_buffer_head] = data;
|
||||
rx_buffer_head = next_head;
|
||||
|
||||
#if ENABLE_XONXOFF
|
||||
if ((get_rx_buffer_count() >= RX_BUFFER_FULL) && flow_ctrl != XOFF_SENT) {
|
||||
flow_ctrl = SEND_XOFF;
|
||||
UCSR0B |= (1 << UDRIE0); // Force TX
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,4 +196,8 @@ ISR(USART_RX_vect)
|
||||
void serial_reset_read_buffer()
|
||||
{
|
||||
rx_buffer_tail = rx_buffer_head;
|
||||
|
||||
#if ENABLE_XONXOFF
|
||||
flow_ctrl = XON_SENT;
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user