SD card: actually read the characters from the file.

Next to the implementation of sd_read_byte() as well as M24 and
M25, yet another demo: read the file and write it to the serial
line, to show correctness of the implementation.
This commit is contained in:
Markus Hitter 2015-07-01 16:27:37 +02:00
parent 5a0f7a0e72
commit d3f548a895
5 changed files with 97 additions and 7 deletions

View File

@ -35,6 +35,12 @@ uint8_t tool;
/// the tool to be changed when we get an M6 /// the tool to be changed when we get an M6
uint8_t next_tool; 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. //? to the next M23.
sd_open(gcode_str_buf); sd_open(gcode_str_buf);
break; 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 */ #endif /* SD */
case 82: case 82:

View File

@ -3,6 +3,14 @@
#include "gcode_parse.h" #include "gcode_parse.h"
enum gcode_source {
GCODE_SOURCE_SERIAL = 0b00000001,
GCODE_SOURCE_SD = 0b00000010,
};
extern enum gcode_source gcode_sources;
// the current tool // the current tool
extern uint8_t tool; extern uint8_t tool;
// the tool to be changed when we get an M6 // the tool to be changed when we get an M6

View File

@ -36,6 +36,7 @@
#include "dda_queue.h" #include "dda_queue.h"
#include "dda.h" #include "dda.h"
#include "gcode_parse.h" #include "gcode_parse.h"
#include "gcode_process.h"
#include "timer.h" #include "timer.h"
#include "temp.h" #include "temp.h"
#include "sermsg.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 is full, no point in reading chars- host will just have to wait
if (queue_full() == 0) { if (queue_full() == 0) {
uint8_t c;
if (serial_rxchars() != 0) { if (serial_rxchars() != 0) {
uint8_t c = serial_popchar(); c = serial_popchar();
gcode_parse_char(c); 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 #ifdef CANNED_CYCLE
/** /**
WARNING! WARNING!

46
sd.c
View File

@ -10,10 +10,15 @@
#include "serial.h" #include "serial.h"
#include "sersendf.h" #include "sersendf.h"
#define SD_BUFFER_SIZE 16
static FATFS sdfile; static FATFS sdfile;
static FRESULT result; 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. /** Initialize SPI for SD card reading.
*/ */
void sd_init(void) { void sd_init(void) {
@ -78,14 +83,43 @@ void sd_list(const char* path) {
*/ */
void sd_open(const char* filename) { void sd_open(const char* filename) {
result = pf_open(filename); result = pf_open(filename);
if (result == FR_OK) { 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 {
sersendf_P(PSTR("E: failed to open file. (%su)"), result); 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 */ #endif /* SD */

2
sd.h
View File

@ -25,6 +25,8 @@ void sd_list(const char* path);
void sd_open(const char* filename); void sd_open(const char* filename);
uint8_t sd_read_char(void);
#endif /* SD_CARD_SELECT_PIN */ #endif /* SD_CARD_SELECT_PIN */
#endif /* _SD_H */ #endif /* _SD_H */