SD card: finally(!) implement printing from SD card.

Turned out to be pretty easy with all the more complex bits
already in place.

Strategy is to always parse a full line from one of the sources.
Accordingly, simply sending a character on the serial line stops
reading from SD until the line coming in over serial is completed.
This commit is contained in:
Markus Hitter 2015-07-06 18:39:39 +02:00
parent c7b134bc65
commit 23be2d1449
3 changed files with 27 additions and 15 deletions

View File

@ -42,6 +42,13 @@ uint8_t next_tool;
*/ */
enum gcode_source gcode_sources = GCODE_SOURCE_SERIAL; enum gcode_source gcode_sources = GCODE_SOURCE_SERIAL;
/** Bitfield for the current source of G-code.
Only one bit should be set at a time. The bit is set at start reading a
line and cleared when a line is done.
*/
enum gcode_source gcode_active = 0;
/************************************************************************//** /************************************************************************//**
\brief Processes command stored in global \ref next_target. \brief Processes command stored in global \ref next_target.

View File

@ -10,6 +10,7 @@ enum gcode_source {
extern enum gcode_source gcode_sources; extern enum gcode_source gcode_sources;
extern enum gcode_source gcode_active;
// the current tool // the current tool
extern uint8_t tool; extern uint8_t tool;

View File

@ -273,23 +273,31 @@ int main (void)
if (queue_full() == 0) { if (queue_full() == 0) {
uint8_t c; uint8_t c;
if (serial_rxchars() != 0) { if (( ! gcode_active || gcode_active & GCODE_SOURCE_SERIAL) &&
serial_rxchars() != 0) {
gcode_active = GCODE_SOURCE_SERIAL;
c = serial_popchar(); c = serial_popchar();
gcode_parse_char(c); gcode_parse_char(c);
if (c == '\r' || c == '\n')
gcode_active = 0;
} }
#ifdef SD #ifdef SD
if (gcode_sources & GCODE_SOURCE_SD) { if (( ! gcode_active || gcode_active & GCODE_SOURCE_SD) &&
gcode_sources & GCODE_SOURCE_SD) {
c = sd_read_char(); c = sd_read_char();
/* Demo code: just read all the bytes without doing anything with
them to allow measuring how long it takes to read a file. Report
over serial when the file is done. */
if (c == 0) { if (c == 0) {
serial_writestr_P(PSTR("\nSD file done.\n")); serial_writestr_P(PSTR("\nSD file done.\n"));
gcode_sources &= ! GCODE_SOURCE_SD; gcode_sources &= ! GCODE_SOURCE_SD;
// There is no pf_close(), subsequent reads will stick at EOF // There is no pf_close(), subsequent reads will stick at EOF
// and return zeros. // and return zeros.
} }
else {
gcode_active = GCODE_SOURCE_SD;
gcode_parse_char(c);
if (c == '\r' || c == '\n')
gcode_active = 0;
}
} }
#endif #endif
@ -299,17 +307,13 @@ int main (void)
This code works on a per-character basis. This code works on a per-character basis.
Any data received over serial WILL be randomly distributed through Unlike with SD reading code above and for historical reasons (was
the canned gcode, and you'll have a big mess! a quicky doing its job, before SD card was implemented), any data
received over serial WILL be randomly distributed through the canned
G-code, and you'll have a big mess!
The solution is to either store gcode parser state with each source, The solution is to join the strategy above and make canned G-code
or only parse a line at a time. a third G-code source next to serial and SD.
This will take extra ram, and may be out of scope for the Teacup
project.
If ever print-from-SD card is implemented, these changes may become
necessary.
*/ */
static uint32_t canned_gcode_pos = 0; static uint32_t canned_gcode_pos = 0;