diff --git a/gcode_process.c b/gcode_process.c index 25910cf..9b809c8 100644 --- a/gcode_process.c +++ b/gcode_process.c @@ -35,6 +35,12 @@ uint8_t tool; /// the tool to be changed when we get an M6 uint8_t next_tool; +/** Bitfield for available sources of G-code. + + A typical source is the SD card or canned G-code. Serial is currently never + turned off. +*/ +enum gcode_source gcode_sources = GCODE_SOURCE_SERIAL; /************************************************************************//** @@ -406,6 +412,23 @@ void process_gcode_command() { //? to the next M23. sd_open(gcode_str_buf); break; + + case 24: + //? --- M24: start/resume SD print. --- + //? + //? This makes the SD card available as a G-code source. File is the + //? one selected with M23. + gcode_sources |= GCODE_SOURCE_SD; + break; + + case 25: + //? --- M25: pause SD print. --- + //? + //? This removes the SD card from the bitfield of available G-code + //? sources. The file is kept open. The position inside the file + //? is kept as well, to allow resuming. + gcode_sources &= ! GCODE_SOURCE_SD; + break; #endif /* SD */ case 82: diff --git a/gcode_process.h b/gcode_process.h index 4086b84..21a8b82 100644 --- a/gcode_process.h +++ b/gcode_process.h @@ -3,6 +3,14 @@ #include "gcode_parse.h" +enum gcode_source { + GCODE_SOURCE_SERIAL = 0b00000001, + GCODE_SOURCE_SD = 0b00000010, +}; + + +extern enum gcode_source gcode_sources; + // the current tool extern uint8_t tool; // the tool to be changed when we get an M6 diff --git a/mendel.c b/mendel.c index 23cbf76..458050c 100644 --- a/mendel.c +++ b/mendel.c @@ -36,6 +36,7 @@ #include "dda_queue.h" #include "dda.h" #include "gcode_parse.h" +#include "gcode_process.h" #include "timer.h" #include "temp.h" #include "sermsg.h" @@ -270,11 +271,33 @@ int main (void) { // if queue is full, no point in reading chars- host will just have to wait if (queue_full() == 0) { + uint8_t c; + if (serial_rxchars() != 0) { - uint8_t c = serial_popchar(); + c = serial_popchar(); gcode_parse_char(c); } + #ifdef SD + #include "delay.h" + + if (gcode_sources & GCODE_SOURCE_SD) { + c = sd_read_char(); + /* Demo code here again, just write the character to the serial line, + leading to the file written as-is to there. This may help + demonstrating correctness of the implementation. */ + if (c != 0) { + serial_writechar(c); + delay_us(1000); + } + else { + gcode_sources &= ! GCODE_SOURCE_SD; + // There is no pf_close(), subsequent reads will stick at EOF + // and return zeros. + } + } + #endif + #ifdef CANNED_CYCLE /** WARNING! diff --git a/sd.c b/sd.c index 6fe93d1..697b88b 100644 --- a/sd.c +++ b/sd.c @@ -10,10 +10,15 @@ #include "serial.h" #include "sersendf.h" +#define SD_BUFFER_SIZE 16 + static FATFS sdfile; static FRESULT result; +static uint8_t sd_buffer[SD_BUFFER_SIZE]; +static uint8_t sd_buffer_ptr = SD_BUFFER_SIZE; + /** Initialize SPI for SD card reading. */ void sd_init(void) { @@ -78,14 +83,43 @@ void sd_list(const char* path) { */ void sd_open(const char* filename) { result = pf_open(filename); - if (result == FR_OK) { - // To demonstrate this works, open the file and show its size. - // Actually, the file name isn't stored, so we can't read it back :-) - sersendf_P(PSTR("Successfully opened file with %lu bytes."), sdfile.fsize); - } - else { + if (result != FR_OK) { sersendf_P(PSTR("E: failed to open file. (%su)"), result); } } +/** Read a character from a file. + + \return The character read, or zero if there is no such character (e.g. EOF). + + In principle it'd be possible to read the file character by character. + However, Before too long this will cause the printer to read G-code from this file + until done or until stopped by G-code coming in over the serial line. +*/ +uint8_t sd_read_char(void) { + UINT read; + uint8_t this_char; + + if (sd_buffer_ptr == SD_BUFFER_SIZE) { + result = pf_read(sd_buffer, SD_BUFFER_SIZE, &read); + if (result != FR_OK) { + sersendf_P(PSTR("E: failed to read from file. (%su)"), result); + return 0; + } + if (read < SD_BUFFER_SIZE) { + sd_buffer[read] = 0; // A zero marks EOF. + } + + sd_buffer_ptr = 0; + } + + this_char = sd_buffer[sd_buffer_ptr]; + if (this_char == 0) + sd_buffer_ptr = SD_BUFFER_SIZE; // Start over, perhaps with next file. + else + sd_buffer_ptr++; + + return this_char; +} + #endif /* SD */ diff --git a/sd.h b/sd.h index 7252add..b7e58a4 100644 --- a/sd.h +++ b/sd.h @@ -25,6 +25,8 @@ void sd_list(const char* path); void sd_open(const char* filename); +uint8_t sd_read_char(void); + #endif /* SD_CARD_SELECT_PIN */ #endif /* _SD_H */