Serial: postpone sending "ok" until a slot is free.
Previously acknoledgement was sent as soon as the command was parsed. Accordingly, the host would send the next command and this command would wait in the RX buffer without being parsed. This worked reasonably, unless an incoming line of G-code was longer than the RX buffer, in which case the line end was dropped and parsing of the line never completed. With a 64 bytes buffer on AVR this was rarely the case, with the 16 bytes hardware buffer on ARM LPC1114 it happens regularly. And there's no recovering from such a situation. This should solve issue #52.
This commit is contained in:
parent
a1feb32fe3
commit
77630167e7
|
|
@ -387,9 +387,9 @@ uint8_t gcode_parse_char(uint8_t c) {
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
// process
|
// process
|
||||||
serial_writestr_P(PSTR("ok "));
|
|
||||||
process_gcode_command();
|
process_gcode_command();
|
||||||
serial_writechar('\n');
|
|
||||||
|
// Acknowledgement ("ok") is sent in the main loop, in mendel.c.
|
||||||
|
|
||||||
// expect next line number
|
// expect next line number
|
||||||
if (next_target.seen_N == 1)
|
if (next_target.seen_N == 1)
|
||||||
|
|
|
||||||
24
mendel.c
24
mendel.c
|
|
@ -261,6 +261,8 @@ int main (int argc, char** argv)
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
uint8_t c, line_done, ack_waiting = 0;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
|
|
@ -268,15 +270,33 @@ int main (void)
|
||||||
{
|
{
|
||||||
// if queue is full, no point in reading chars- host will just have to wait
|
// if queue is full, no point in reading chars- host will just have to wait
|
||||||
if (queue_full() == 0) {
|
if (queue_full() == 0) {
|
||||||
uint8_t c, line_done;
|
/**
|
||||||
|
Postpone sending acknowledgement until there's a free slot in the
|
||||||
|
movement queue. This way the host waits with sending the next line
|
||||||
|
until it can be processed immediately. As a result, the serial receive
|
||||||
|
queue is always almost empty; it exists only for receiving via XON/XOFF
|
||||||
|
flow control. Another result is, the incoming line can be longer than
|
||||||
|
the receiving buffer, see Github issue #52.
|
||||||
|
|
||||||
|
At the time of the introduction of this strategy gcode_parse_char()
|
||||||
|
parsed a single character in 100 to 400 CPU clocks, processing
|
||||||
|
the line end took some 30'000 clocks. 115200 baud mean one character
|
||||||
|
incoming every about 1250 CPU clocks on AVR 16 MHz.
|
||||||
|
*/
|
||||||
|
if (ack_waiting) {
|
||||||
|
serial_writestr_P(PSTR("ok\n"));
|
||||||
|
ack_waiting = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (( ! gcode_active || gcode_active & GCODE_SOURCE_SERIAL) &&
|
if (( ! gcode_active || gcode_active & GCODE_SOURCE_SERIAL) &&
|
||||||
serial_rxchars() != 0) {
|
serial_rxchars() != 0) {
|
||||||
gcode_active = GCODE_SOURCE_SERIAL;
|
gcode_active = GCODE_SOURCE_SERIAL;
|
||||||
c = serial_popchar();
|
c = serial_popchar();
|
||||||
line_done = gcode_parse_char(c);
|
line_done = gcode_parse_char(c);
|
||||||
if (line_done)
|
if (line_done) {
|
||||||
gcode_active = 0;
|
gcode_active = 0;
|
||||||
|
ack_waiting = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SD
|
#ifdef SD
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue