Reprap's gcode interface has two types of commands- One type of command returns data immediately, and the other causes some action that must occur at the correct time in relation to actions before and after. These are referred to as unbuffered and buffered respectively on GCodes.
Most firmwares implement a queue. This means that (amongst other advantages) unbuffered commands can be serviced while buffered commands are running. However, when the queue is filled, the firmware MUST stop accepting commands or it risks over-running the queue.
There is no way to tell whether the next command is buffered or unbuffered, and no way to tell the host that we have received a command but the queue is full so don't send any more buffered commands.
I propose a simple addition to our current protocol:
This feature is selected with Protocol Feature Negotiation because the firmware MUST know that the host supports it or it won't work.
Instead of our simple 'ok' response which currently serves the dual purpose of telling the host that we received the command and we're ready for another one, we add a keyword after ok to indicate whether or not there's room in the buffer.
This means that 'ok' means ONLY that the command was received, it no longer means there's room in the buffer - instead we use the keyword 'buffer' for that. Eg (assuming a 4-move buffer):
M115 ok FIRMWARE_NAME:Teacup FEATURES:0/dual-band... M118 P1 (enable dual-band) ok buffer M109 S212 (set temp to 212C and wait. this blocks the buffer until the extruder reaches 212C) ok buffer G1 Y10 ok buffer G1 X50 ok buffer G1 Y50 ok (here our buffer becomes full- no more G1s!)
M105 is an unbuffered command that immediately returns information. We can send it when the buffer is full, and we must send something to know when the buffer has cleared
M105 ok T:186.5 M105 ok T212.25 M105 ok T211.75 M105 ok T212.5 buffer (here our buffer has cleared a slot, we can send the next G1) G1 X0 Y0 ok buffer (this indicates that there's still room in our buffer, we can keep sending moves) ...
I propose that we also support a reply word in the form Qn/ms where n is the ringbuffer tail (index of currently running move) and m is the ringbuffer head (index of most recently added move), and s is 'E' for empty and 'F' for full (and not present or space for neither). This allows the host to know which move is currently being executed if it keeps track. This is not necessary for dual-band, but could be used both as a backup information source and an 'executing move' indicator.
GCODE buffer multiline proposal This may be related