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:
parent
5a0f7a0e72
commit
d3f548a895
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
25
mendel.c
25
mendel.c
|
|
@ -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
46
sd.c
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue