Fix of a power panic print stop.
This commit is contained in:
parent
641c21a97b
commit
582a6270b0
@ -356,7 +356,10 @@ const unsigned int dropsegments=5; //everything with less than this number of st
|
||||
//The ASCII buffer for receiving from the serial:
|
||||
#define MAX_CMD_SIZE 96
|
||||
#define BUFSIZE 4
|
||||
#define CMDHDRSIZE 2
|
||||
// The command header contains the following values:
|
||||
// 1st byte: the command source (CMDBUFFER_CURRENT_TYPE_USB, CMDBUFFER_CURRENT_TYPE_SDCARD, CMDBUFFER_CURRENT_TYPE_UI or CMDBUFFER_CURRENT_TYPE_CHAINED)
|
||||
// 2nd and 3rd byte (LSB first) contains a 16bit length of a command including its preceding comments.
|
||||
#define CMDHDRSIZE 3
|
||||
|
||||
|
||||
// Firmware based and LCD controlled retract
|
||||
|
@ -108,8 +108,8 @@ bool cmdqueue_could_enqueue_front(int len_asked)
|
||||
cmdqueue_pop_front();
|
||||
cmdbuffer_front_already_processed = true;
|
||||
}
|
||||
if (bufindr == bufindw && buflen > 0)
|
||||
// Full buffer.
|
||||
if (bufindr == bufindw && buflen > 0)
|
||||
// Full buffer.
|
||||
return false;
|
||||
// Adjust the end of the write buffer based on whether a partial line is in the receive buffer.
|
||||
int endw = (serial_count > 0) ? (bufindw + MAX_CMD_SIZE + 1) : bufindw;
|
||||
@ -137,19 +137,21 @@ bool cmdqueue_could_enqueue_front(int len_asked)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Could one enqueue a command of lenthg len_asked into the buffer,
|
||||
// Could one enqueue a command of length len_asked into the buffer,
|
||||
// while leaving CMDBUFFER_RESERVE_FRONT at the start?
|
||||
// If yes, adjust bufindw to the new position, where the new command could be enqued.
|
||||
// len_asked does not contain the zero terminator size.
|
||||
bool cmdqueue_could_enqueue_back(int len_asked)
|
||||
// This function may update bufindw, therefore for the power panic to work, this function must be called
|
||||
// with the interrupts disabled!
|
||||
bool cmdqueue_could_enqueue_back(int len_asked, bool atomic_update)
|
||||
{
|
||||
// MAX_CMD_SIZE has to accommodate the zero terminator.
|
||||
if (len_asked >= MAX_CMD_SIZE)
|
||||
return false;
|
||||
|
||||
if (bufindr == bufindw && buflen > 0)
|
||||
// Full buffer.
|
||||
return false;
|
||||
if (bufindr == bufindw && buflen > 0)
|
||||
// Full buffer.
|
||||
return false;
|
||||
|
||||
if (serial_count > 0) {
|
||||
// If there is some data stored starting at bufindw, len_asked is certainly smaller than
|
||||
@ -172,7 +174,12 @@ bool cmdqueue_could_enqueue_back(int len_asked)
|
||||
// Mark the rest of the buffer as used.
|
||||
memset(cmdbuffer+bufindw, 0, sizeof(cmdbuffer)-bufindw);
|
||||
// and point to the start.
|
||||
// Be careful! The bufindw needs to be changed atomically for the power panic & filament panic to work.
|
||||
if (atomic_update)
|
||||
cli();
|
||||
bufindw = 0;
|
||||
if (atomic_update)
|
||||
sei();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
@ -193,7 +200,12 @@ bool cmdqueue_could_enqueue_back(int len_asked)
|
||||
// Mark the rest of the buffer as used.
|
||||
memset(cmdbuffer+bufindw, 0, sizeof(cmdbuffer)-bufindw);
|
||||
// and point to the start.
|
||||
// Be careful! The bufindw needs to be changed atomically for the power panic & filament panic to work.
|
||||
if (atomic_update)
|
||||
cli();
|
||||
bufindw = 0;
|
||||
if (atomic_update)
|
||||
sei();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -337,30 +349,30 @@ void repeatcommand_front()
|
||||
|
||||
bool is_buffer_empty()
|
||||
{
|
||||
if (buflen == 0) return true;
|
||||
else return false;
|
||||
if (buflen == 0) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
void get_command()
|
||||
{
|
||||
// Test and reserve space for the new command string.
|
||||
if (!cmdqueue_could_enqueue_back(MAX_CMD_SIZE - 1))
|
||||
return;
|
||||
|
||||
bool rx_buffer_full = false; //flag that serial rx buffer is full
|
||||
if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE - 1, true))
|
||||
return;
|
||||
|
||||
bool rx_buffer_full = false; //flag that serial rx buffer is full
|
||||
|
||||
while (MYSERIAL.available() > 0) {
|
||||
if (MYSERIAL.available() == RX_BUFFER_SIZE - 1) { //compare number of chars buffered in rx buffer with rx buffer size
|
||||
SERIAL_ECHOLNPGM("Full RX Buffer"); //if buffer was full, there is danger that reading of last gcode will not be completed
|
||||
rx_buffer_full = true; //sets flag that buffer was full
|
||||
}
|
||||
if (MYSERIAL.available() == RX_BUFFER_SIZE - 1) { //compare number of chars buffered in rx buffer with rx buffer size
|
||||
SERIAL_ECHOLNPGM("Full RX Buffer"); //if buffer was full, there is danger that reading of last gcode will not be completed
|
||||
rx_buffer_full = true; //sets flag that buffer was full
|
||||
}
|
||||
char serial_char = MYSERIAL.read();
|
||||
if (selectedSerialPort == 1)
|
||||
{
|
||||
selectedSerialPort = 0;
|
||||
MYSERIAL.write(serial_char); // for debuging serial line 2 in farm_mode
|
||||
selectedSerialPort = 1;
|
||||
}
|
||||
if (selectedSerialPort == 1)
|
||||
{
|
||||
selectedSerialPort = 0;
|
||||
MYSERIAL.write(serial_char); // for debuging serial line 2 in farm_mode
|
||||
selectedSerialPort = 1;
|
||||
}
|
||||
TimeSent = millis();
|
||||
TimeNow = millis();
|
||||
|
||||
@ -443,10 +455,10 @@ void get_command()
|
||||
}
|
||||
} // end of '*' command
|
||||
if ((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'G')) != NULL) {
|
||||
if (! IS_SD_PRINTING) {
|
||||
usb_printing_counter = 10;
|
||||
is_usb_printing = true;
|
||||
}
|
||||
if (! IS_SD_PRINTING) {
|
||||
usb_printing_counter = 10;
|
||||
is_usb_printing = true;
|
||||
}
|
||||
if (Stopped == true) {
|
||||
int gcode = strtol(strchr_pointer+1, NULL, 10);
|
||||
if (gcode >= 0 && gcode <= 3) {
|
||||
@ -481,7 +493,7 @@ void get_command()
|
||||
serial_count = 0; //clear buffer
|
||||
// Don't call cmdqueue_could_enqueue_back if there are no characters waiting
|
||||
// in the queue, as this function will reserve the memory.
|
||||
if (MYSERIAL.available() == 0 || ! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1))
|
||||
if (MYSERIAL.available() == 0 || ! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1, true))
|
||||
return;
|
||||
} // end of "end of line" processing
|
||||
else {
|
||||
@ -509,12 +521,12 @@ void get_command()
|
||||
}
|
||||
}
|
||||
|
||||
//add comment
|
||||
if (rx_buffer_full == true && serial_count > 0) { //if rx buffer was full and string was not properly terminated
|
||||
rx_buffer_full = false;
|
||||
bufindw = bufindw - serial_count; //adjust tail of the buffer to prepare buffer for writing new command
|
||||
serial_count = 0;
|
||||
}
|
||||
//add comment
|
||||
if (rx_buffer_full == true && serial_count > 0) { //if rx buffer was full and string was not properly terminated
|
||||
rx_buffer_full = false;
|
||||
bufindw = bufindw - serial_count; //adjust tail of the buffer to prepare buffer for writing new command
|
||||
serial_count = 0;
|
||||
}
|
||||
|
||||
#ifdef SDSUPPORT
|
||||
if(!card.sdprinting || serial_count!=0){
|
||||
@ -529,40 +541,46 @@ void get_command()
|
||||
|
||||
static bool stop_buffering=false;
|
||||
if(buflen==0) stop_buffering=false;
|
||||
unsigned char sd_count = 0;
|
||||
union {
|
||||
struct {
|
||||
char lo;
|
||||
char hi;
|
||||
} lohi;
|
||||
uint16_t value;
|
||||
} sd_count;
|
||||
sd_count.value = 0;
|
||||
// Reads whole lines from the SD card. Never leaves a half-filled line in the cmdbuffer.
|
||||
while( !card.eof() && !stop_buffering) {
|
||||
int16_t n=card.get();
|
||||
sd_count++;
|
||||
++ sd_count.value;
|
||||
char serial_char = (char)n;
|
||||
if(serial_char == '\n' ||
|
||||
serial_char == '\r' ||
|
||||
(serial_char == '#' && comment_mode == false) ||
|
||||
(serial_char == ':' && comment_mode == false) ||
|
||||
serial_count >= (MAX_CMD_SIZE - 1)||n==-1)
|
||||
((serial_char == '#' || serial_char == ':') && comment_mode == false) ||
|
||||
serial_count >= (MAX_CMD_SIZE - 1) || n==-1)
|
||||
{
|
||||
if(card.eof()){
|
||||
SERIAL_PROTOCOLLNRPGM(MSG_FILE_PRINTED);
|
||||
stoptime=millis();
|
||||
char time[30];
|
||||
unsigned long t=(stoptime-starttime-pause_time)/1000;
|
||||
pause_time = 0;
|
||||
pause_time = 0;
|
||||
int hours, minutes;
|
||||
minutes=(t/60)%60;
|
||||
hours=t/60/60;
|
||||
save_statistics(total_filament_used, t);
|
||||
sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
|
||||
save_statistics(total_filament_used, t);
|
||||
sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
|
||||
SERIAL_ECHO_START;
|
||||
SERIAL_ECHOLN(time);
|
||||
lcd_setstatus(time);
|
||||
card.printingHasFinished();
|
||||
card.checkautostart(true);
|
||||
|
||||
if (farm_mode)
|
||||
{
|
||||
prusa_statistics(6);
|
||||
lcd_commands_type = LCD_COMMAND_FARM_MODE_CONFIRM;
|
||||
}
|
||||
if (farm_mode)
|
||||
{
|
||||
prusa_statistics(6);
|
||||
lcd_commands_type = LCD_COMMAND_FARM_MODE_CONFIRM;
|
||||
}
|
||||
|
||||
}
|
||||
if(serial_char=='#')
|
||||
@ -570,40 +588,50 @@ void get_command()
|
||||
|
||||
if(!serial_count)
|
||||
{
|
||||
comment_mode = false; //for new command
|
||||
return; //if empty line
|
||||
// This is either an empty line, or a line with just a comment.
|
||||
// Continue to the following line, and continue accumulating the number of bytes
|
||||
// read from the sdcard into sd_count,
|
||||
// so that the lenght of the already read empty lines and comments will be added
|
||||
// to the following non-empty line.
|
||||
comment_mode = false;
|
||||
continue; //if empty line
|
||||
}
|
||||
// The new command buffer could be updated non-atomically, because it is not yet considered
|
||||
// to be inside the active queue.
|
||||
cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_SDCARD;
|
||||
cmdbuffer[bufindw+1] = sd_count.lohi.lo;
|
||||
cmdbuffer[bufindw+2] = sd_count.lohi.hi;
|
||||
cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0; //terminate string
|
||||
uint8_t len = strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
|
||||
// Calculate the length before disabling the interrupts.
|
||||
uint8_t len = strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
|
||||
|
||||
cli();
|
||||
cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_SDCARD;
|
||||
cmdbuffer[bufindw+1] = sd_count;
|
||||
/* SERIAL_ECHOPGM("SD cmd(");
|
||||
MYSERIAL.print(sd_count, DEC);
|
||||
SERIAL_ECHOPGM(") ");
|
||||
SERIAL_ECHOLN(cmdbuffer+bufindw+CMDHDRSIZE);*/
|
||||
// SERIAL_ECHOPGM("cmdbuffer:");
|
||||
// MYSERIAL.print(cmdbuffer);
|
||||
/* SERIAL_ECHOPGM("SD cmd(");
|
||||
MYSERIAL.print(sd_count.value, DEC);
|
||||
SERIAL_ECHOPGM(") ");
|
||||
SERIAL_ECHOLN(cmdbuffer+bufindw+CMDHDRSIZE);*/
|
||||
// SERIAL_ECHOPGM("cmdbuffer:");
|
||||
// MYSERIAL.print(cmdbuffer);
|
||||
// SERIAL_ECHOPGM("buflen:");
|
||||
// MYSERIAL.print(buflen+1);
|
||||
|
||||
cli();
|
||||
++ buflen;
|
||||
// SERIAL_ECHOPGM("buflen:");
|
||||
// MYSERIAL.print(buflen);
|
||||
bufindw += len;
|
||||
sdpos_atomic = card.get_sdpos();
|
||||
sdpos_atomic = card.get_sdpos();
|
||||
if (bufindw == sizeof(cmdbuffer))
|
||||
bufindw = 0;
|
||||
sei();
|
||||
sei();
|
||||
|
||||
comment_mode = false; //for new command
|
||||
comment_mode = false; //for new command
|
||||
serial_count = 0; //clear buffer
|
||||
// The following line will reserve buffer space if available.
|
||||
if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1))
|
||||
if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1, true))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(serial_char == ';') comment_mode = true;
|
||||
if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
|
||||
else if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,17 +640,26 @@ void get_command()
|
||||
|
||||
uint16_t cmdqueue_calc_sd_length()
|
||||
{
|
||||
int _buflen = buflen;
|
||||
int _bufindr = bufindr;
|
||||
uint16_t sdlen = 0;
|
||||
while (_buflen--)
|
||||
{
|
||||
if (cmdbuffer[_bufindr] == CMDBUFFER_CURRENT_TYPE_SDCARD)
|
||||
sdlen += cmdbuffer[_bufindr + 1];
|
||||
//skip header, skip command
|
||||
for (_bufindr += CMDHDRSIZE; cmdbuffer[_bufindr] != 0; ++ _bufindr) ;
|
||||
//skip zeros
|
||||
for (++ _bufindr; _bufindr < sizeof(cmdbuffer) && cmdbuffer[_bufindr] == 0; ++ _bufindr) ;
|
||||
}
|
||||
return sdlen;
|
||||
}
|
||||
int _buflen = buflen;
|
||||
int _bufindr = bufindr;
|
||||
union {
|
||||
struct {
|
||||
char lo;
|
||||
char hi;
|
||||
} lohi;
|
||||
uint16_t value;
|
||||
} sdlen;
|
||||
sdlen.value = 0;
|
||||
while (_buflen--)
|
||||
{
|
||||
if (cmdbuffer[_bufindr] == CMDBUFFER_CURRENT_TYPE_SDCARD) {
|
||||
sdlen.lohi.lo += cmdbuffer[_bufindr + 1];
|
||||
sdlen.lohi.hi += cmdbuffer[_bufindr + 2];
|
||||
}
|
||||
//skip header, skip command
|
||||
for (_bufindr += CMDHDRSIZE; cmdbuffer[_bufindr] != 0; ++ _bufindr) ;
|
||||
//skip zeros
|
||||
for (++ _bufindr; _bufindr < sizeof(cmdbuffer) && cmdbuffer[_bufindr] == 0; ++ _bufindr) ;
|
||||
}
|
||||
return sdlen.value;
|
||||
}
|
@ -54,9 +54,11 @@ extern long Stopped_gcode_LastN;
|
||||
extern bool cmdqueue_pop_front();
|
||||
extern void cmdqueue_reset();
|
||||
extern bool cmdqueue_could_enqueue_front(int len_asked);
|
||||
extern bool cmdqueue_could_enqueue_back(int len_asked);
|
||||
extern bool cmdqueue_could_enqueue_back(int len_asked, bool atomic_update = false);
|
||||
#ifdef CMDBUFFER_DEBUG
|
||||
extern void cmdqueue_dump_to_serial_single_line(int nr, const char *p);
|
||||
extern void cmdqueue_dump_to_serial();
|
||||
#endif /* CMDBUFFER_DEBUG */
|
||||
extern void enquecommand(const char *cmd, bool from_progmem);
|
||||
extern void enquecommand_front(const char *cmd, bool from_progmem);
|
||||
extern void repeatcommand_front();
|
||||
|
@ -1300,9 +1300,17 @@ void planner_queue_min_reset()
|
||||
}
|
||||
#endif /* PLANNER_DIAGNOSTICS */
|
||||
|
||||
void planner_add_sd_length(uint8_t sdlen)
|
||||
void planner_add_sd_length(uint16_t sdlen)
|
||||
{
|
||||
block_buffer[block_buffer_tail].sdlen += sdlen;
|
||||
if (block_buffer_head != block_buffer_tail) {
|
||||
// The planner buffer is not empty. Get the index of the last buffer line entered,
|
||||
// which is (block_buffer_head - 1) modulo BLOCK_BUFFER_SIZE.
|
||||
unsigned char last = (block_buffer_head + BLOCK_BUFFER_SIZE - 1) & (BLOCK_BUFFER_SIZE - 1);
|
||||
block_buffer[last].sdlen += sdlen;
|
||||
} else {
|
||||
// There is no line stored in the planner buffer, which means the last command does not need to be revertible,
|
||||
// at a power panic, so the length of this command may be forgotten.
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t planner_calc_sd_length()
|
||||
|
@ -159,7 +159,11 @@ extern unsigned long axis_steps_per_sqr_second[NUM_AXIS];
|
||||
|
||||
|
||||
extern block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instfructions
|
||||
extern volatile unsigned char block_buffer_head; // Index of the next block to be pushed
|
||||
// Index of the next block to be pushed into the planner queue.
|
||||
extern volatile unsigned char block_buffer_head;
|
||||
// Index of the first block in the planner queue.
|
||||
// This is the block, which is being currently processed by the stepper routine,
|
||||
// or which is first to be processed by the stepper routine.
|
||||
extern volatile unsigned char block_buffer_tail;
|
||||
// Called when the current block is no longer needed. Discards the block and makes the memory
|
||||
// available for new blocks.
|
||||
@ -170,7 +174,10 @@ FORCE_INLINE void plan_discard_current_block()
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the current block. Returns NULL if buffer empty
|
||||
// Gets the current block. This is the block to be exectuted by the stepper routine.
|
||||
// Mark this block as busy, so its velocities and acceperations will be no more recalculated
|
||||
// by the planner routine.
|
||||
// Returns NULL if buffer empty
|
||||
FORCE_INLINE block_t *plan_get_current_block()
|
||||
{
|
||||
if (block_buffer_head == block_buffer_tail) {
|
||||
@ -220,6 +227,6 @@ extern uint8_t planner_queue_min();
|
||||
extern void planner_queue_min_reset();
|
||||
#endif /* PLANNER_DIAGNOSTICS */
|
||||
|
||||
extern void planner_add_sd_length(uint8_t sdlen);
|
||||
extern void planner_add_sd_length(uint16_t sdlen);
|
||||
|
||||
extern uint16_t planner_calc_sd_length();
|
||||
|
Loading…
Reference in New Issue
Block a user