Various fixes for MarlinUI and ExtUI (#12439)

This commit is contained in:
Marcio Teixeira
2018-11-17 21:21:44 -07:00
committed by Scott Lahteine
parent d3605cfc26
commit c1e17037e5
24 changed files with 226 additions and 216 deletions

View File

@ -99,10 +99,6 @@ void ST7920_Lite_Status_Screen::write_str_P(PGM_P const str) {
while (char c = pgm_read_byte(p_str++)) write_byte(c);
}
void ST7920_Lite_Status_Screen::write_str(progmem_str str) {
write_str_P((PGM_P)str);
}
void ST7920_Lite_Status_Screen::write_number(const int16_t value, const uint8_t digits/*=3*/) {
char str[7];
PGM_P fmt;
@ -501,11 +497,11 @@ void ST7920_Lite_Status_Screen::draw_progress_bar(const uint8_t value) {
// Draw centered
if (value > 9) {
write_number(value, 4);
write_str(F("% "));
write_str_P(PSTR("% "));
}
else {
write_number(value, 3);
write_str(F("% "));
write_str_P(PSTR("% "));
}
}
@ -558,12 +554,12 @@ void ST7920_Lite_Status_Screen::draw_temps(uint8_t line, const int16_t temp, con
write_number(temp);
if (showTarget) {
write_str(F("\x1A"));
write_byte('\x1A');
write_number(target);
};
if (targetStateChange) {
if (!showTarget) write_str(F(" "));
if (!showTarget) write_str_P(PSTR(" "));
draw_degree_symbol(5, line, !showTarget);
draw_degree_symbol(9, line, showTarget);
}

View File

@ -18,8 +18,6 @@
#include "../../core/macros.h"
#include "../../libs/duration_t.h"
typedef const __FlashStringHelper *progmem_str;
class ST7920_Lite_Status_Screen {
private:
static struct st7920_state_t {
@ -47,7 +45,6 @@ class ST7920_Lite_Status_Screen {
static void write_str(const char *str);
static void write_str(const char *str, const uint8_t len);
static void write_str_P(PGM_P const str);
static void write_str(progmem_str str);
static void write_number(const int16_t value, const uint8_t digits=3);
static void _extended_function_set(const bool extended, const bool graphics);

View File

@ -55,8 +55,7 @@ namespace ExtUI {
void onPrintTimerPaused() {}
void onPrintTimerStopped() {}
void onFilamentRunout() {}
void onStatusChanged(const char* msg) {}
void onStatusChanged(progmem_str msg) {}
void onStatusChanged(const char * const msg) {}
void onFactoryReset() {}
void onLoadSettings() {}
void onStoreSettings() {}

View File

@ -94,6 +94,7 @@ static struct {
} flags;
namespace ExtUI {
#ifdef __SAM3X8E__
/**
* Implement a special millis() to allow time measurement
@ -134,12 +135,7 @@ namespace ExtUI {
return (uint32_t)(currTime / (F_CPU / 8000));
}
#else
// TODO: Implement for AVR
FORCE_INLINE uint32_t safe_millis() { return millis(); }
#endif
#endif // __SAM3X8E__
void delay_us(unsigned long us) {
DELAY_US(us);
@ -287,12 +283,14 @@ namespace ExtUI {
}
void setActiveTool(const extruder_t extruder, bool no_move) {
const uint8_t e = extruder - E0;
#if DO_SWITCH_EXTRUDER || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER)
if (e != active_extruder)
tool_change(e, 0, no_move);
#if EXTRUDERS > 1
const uint8_t e = extruder - E0;
#if DO_SWITCH_EXTRUDER || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER)
if (e != active_extruder)
tool_change(e, 0, no_move);
#endif
active_extruder = e;
#endif
active_extruder = e;
}
extruder_t getActiveTool() {
@ -533,24 +531,26 @@ namespace ExtUI {
float getFeedrate_percent() { return feedrate_percentage; }
void enqueueCommands(progmem_str gcode) {
enqueue_and_echo_commands_P((PGM_P)gcode);
void enqueueCommands_P(PGM_P const gcode) {
enqueue_and_echo_commands_P(gcode);
}
bool isAxisPositionKnown(const axis_t axis) {
return TEST(axis_known_position, axis);
}
progmem_str getFirmwareName_str() {
return F("Marlin " SHORT_BUILD_VERSION);
PGM_P getFirmwareName_str() {
static const char firmware_name[] PROGMEM = "Marlin " SHORT_BUILD_VERSION;
return firmware_name;
}
void setTargetTemp_celsius(float value, const heater_t heater) {
#if HAS_HEATED_BED
if (heater == BED)
thermalManager.setTargetBed(clamp(value,0,200));
if (heater == BED)
thermalManager.setTargetBed(clamp(value,0,200));
else
#endif
thermalManager.setTargetHotend(clamp(value,0,500), heater - H0);
thermalManager.setTargetHotend(clamp(value,0,500), heater - H0);
}
void setTargetTemp_celsius(float value, const extruder_t extruder) {
@ -579,7 +579,7 @@ namespace ExtUI {
}
bool isPrinting() {
return (planner.movesplanned() || IS_SD_PRINTING() || isPrintingFromMedia());
return (planner.movesplanned() || isPrintingFromMedia() || IFSD(IS_SD_PRINTING(), false));
}
bool isMediaInserted() {
@ -593,19 +593,20 @@ namespace ExtUI {
#if ENABLED(PARK_HEAD_ON_PAUSE)
enqueue_and_echo_commands_P(PSTR("M125"));
#endif
ExtUI::onStatusChanged(PSTR(MSG_PRINT_PAUSED));
ui.set_status_P(PSTR(MSG_PRINT_PAUSED));
#endif
}
void resumePrint() {
#if ENABLED(SDSUPPORT)
ui.set_status_P(PSTR(MSG_FILAMENT_CHANGE_RESUME_1));
#if ENABLED(PARK_HEAD_ON_PAUSE)
wait_for_heatup = wait_for_user = false;
enqueue_and_echo_commands_P(PSTR("M24"));
#else
card.startFileprint();
print_job_timer.start();
#endif
ExtUI::onStatusChanged(PSTR(MSG_PRINTING));
#endif
}
@ -613,7 +614,7 @@ namespace ExtUI {
#if ENABLED(SDSUPPORT)
wait_for_heatup = wait_for_user = false;
card.flag.abort_sd_printing = true;
ExtUI::onStatusChanged(PSTR(MSG_PRINT_ABORTED));
ui.set_status_P(PSTR(MSG_PRINT_ABORTED));
#endif
}
@ -621,7 +622,7 @@ namespace ExtUI {
void FileList::refresh() { num_files = 0xFFFF; }
bool FileList::seek(uint16_t pos, bool skip_range_check) {
bool FileList::seek(const uint16_t pos, const bool skip_range_check) {
#if ENABLED(SDSUPPORT)
if (!skip_range_check && pos > (count() - 1)) return false;
const uint16_t nr =
@ -632,6 +633,8 @@ namespace ExtUI {
card.getfilename_sorted(nr);
return card.filename && card.filename[0] != '\0';
#else
return false;
#endif
}
@ -671,7 +674,7 @@ namespace ExtUI {
#endif
}
void FileList::changeDir(const char *dirname) {
void FileList::changeDir(const char * const dirname) {
#if ENABLED(SDSUPPORT)
card.chdir(dirname);
num_files = 0xFFFF;
@ -713,20 +716,6 @@ void MarlinUI::update() {
ExtUI::onIdle();
}
void MarlinUI::setstatus(const char * const message, const bool persist/*=false*/) { ExtUI::onStatusChanged(message); }
void MarlinUI::setstatusPGM(PGM_P const message, int8_t level/*=0*/) { ExtUI::onStatusChanged((progmem_str)message); }
void MarlinUI::setalertstatusPGM(PGM_P const message) { setstatusPGM(message, 0); }
void MarlinUI::status_printf_P(const uint8_t level, const char * const fmt, ...) {
char buff[64];
va_list args;
va_start(args, fmt);
vsnprintf_P(buff, sizeof(buff), fmt, args);
va_end(args);
buff[63] = '\0';
ExtUI::onStatusChanged(buff);
}
void MarlinUI::kill_screen(PGM_P const msg) {
if (!flags.printer_killed) {
flags.printer_killed = true;

View File

@ -45,8 +45,6 @@
#include "../../inc/MarlinConfig.h"
typedef const __FlashStringHelper *progmem_str;
namespace ExtUI {
enum axis_t : uint8_t { X, Y, Z };
@ -62,13 +60,13 @@ namespace ExtUI {
bool isAxisPositionKnown(const axis_t);
bool canMove(const axis_t);
bool canMove(const extruder_t);
void enqueueCommands(progmem_str);
void enqueueCommands_P(PGM_P const);
/**
* Getters and setters
* Should be used by the EXTENSIBLE_UI to query or change Marlin's state.
*/
progmem_str getFirmwareName_str();
PGM_P getFirmwareName_str();
float getActualTemp_celsius(const heater_t);
float getActualTemp_celsius(const extruder_t);
@ -178,7 +176,12 @@ namespace ExtUI {
* safe_millis must be called at least every 1 sec to guarantee time
* yield should be called within lengthy loops
*/
uint32_t safe_millis();
#ifdef __SAM3X8E__
uint32_t safe_millis();
#else
#define safe_millis() millis() // TODO: Implement for AVR
#endif
void delay_us(unsigned long us);
void delay_ms(unsigned long ms);
void yield();
@ -205,14 +208,14 @@ namespace ExtUI {
public:
FileList();
void refresh();
bool seek(uint16_t, bool skip_range_check = false);
bool seek(const uint16_t, const bool skip_range_check = false);
const char *longFilename();
const char *shortFilename();
const char *filename();
bool isDir();
void changeDir(const char *dirname);
void changeDir(const char * const dirname);
void upDir();
bool isAtRootDir();
uint16_t count();
@ -234,8 +237,7 @@ namespace ExtUI {
void onPrintTimerPaused();
void onPrintTimerStopped();
void onFilamentRunout();
void onStatusChanged(const char* msg);
void onStatusChanged(progmem_str msg);
void onStatusChanged(const char * const msg);
void onFactoryReset();
void onStoreSettings();
void onLoadSettings();

View File

@ -480,7 +480,7 @@ void MarlinUI::init() {
/**
* Set an alert.
*/
void MarlinUI::setalertstatusPGM(PGM_P const message) {
void MarlinUI::set_alert_status_P(PGM_P const message) {
write_to_lcd_P(PSTR("{E:"));
write_to_lcd_P(message);
write_to_lcd_P("}");

View File

@ -59,7 +59,7 @@
void lcd_sdcard_stop() {
wait_for_heatup = wait_for_user = false;
card.flag.abort_sd_printing = true;
ui.setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1);
ui.set_status_P(PSTR(MSG_PRINT_ABORTED), -1);
ui.return_to_status();
}

View File

@ -29,6 +29,16 @@
#include "../sd/cardreader.h"
#endif
MarlinUI ui;
#if ENABLED(SDSUPPORT)
#include "../sd/cardreader.h"
#endif
#if ENABLED(EXTENSIBLE_UI)
#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80u)
#endif
#define MAX_MESSAGE_LENGTH 63
uint8_t MarlinUI::status_message_level; // = 0
char MarlinUI::status_message[MAX_MESSAGE_LENGTH + 1];
#endif
#if HAS_SPI_LCD
@ -86,9 +96,7 @@
bool MarlinUI::defer_return_to_status;
#endif
char MarlinUI::status_message[MAX_MESSAGE_LENGTH + 1];
uint8_t MarlinUI::lcd_status_update_delay = 1; // First update one loop delayed
uint8_t MarlinUI::status_message_level; // = 0
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT)
millis_t MarlinUI::next_filament_display; // = 0
@ -475,7 +483,7 @@ void MarlinUI::status_screen() {
void MarlinUI::kill_screen(PGM_P lcd_msg) {
init();
setalertstatusPGM(lcd_msg);
set_alert_status_P(lcd_msg);
draw_kill_screen();
}
@ -674,11 +682,11 @@ void MarlinUI::update() {
if (old_sd_status == 2)
card.beginautostart(); // Initial boot
else
setstatusPGM(PSTR(MSG_SD_INSERTED));
set_status_P(PSTR(MSG_SD_INSERTED));
}
else {
card.release();
if (old_sd_status != 2) setstatusPGM(PSTR(MSG_SD_REMOVED));
if (old_sd_status != 2) set_status_P(PSTR(MSG_SD_REMOVED));
}
refresh();
@ -1083,111 +1091,119 @@ void MarlinUI::update() {
#endif // HAS_ENCODER_ACTION
////////////////////////////////////////////
/////////////// Status Line ////////////////
////////////////////////////////////////////
void MarlinUI::finishstatus(const bool persist) {
#if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0))
UNUSED(persist);
#endif
#if ENABLED(LCD_PROGRESS_BAR)
progress_bar_ms = millis();
#if PROGRESS_MSG_EXPIRE > 0
expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE;
#endif
#endif
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT)
next_filament_display = millis() + 5000UL; // Show status message for 5s
#endif
#if ENABLED(STATUS_MESSAGE_SCROLLING)
status_scroll_offset = 0;
#endif
refresh();
}
bool MarlinUI::has_status() { return (status_message[0] != '\0'); }
void MarlinUI::setstatus(const char * const message, const bool persist) {
if (status_message_level > 0) return;
// Here we have a problem. The message is encoded in UTF8, so
// arbitrarily cutting it will be a problem. We MUST be sure
// that there is no cutting in the middle of a multibyte character!
// Get a pointer to the null terminator
const char* pend = message + strlen(message);
// If length of supplied UTF8 string is greater than
// our buffer size, start cutting whole UTF8 chars
while ((pend - message) > MAX_MESSAGE_LENGTH) {
--pend;
while (!START_OF_UTF8_CHAR(*pend)) --pend;
};
// At this point, we have the proper cut point. Use it
uint8_t maxLen = pend - message;
strncpy(status_message, message, maxLen);
status_message[maxLen] = '\0';
finishstatus(persist);
}
#include <stdarg.h>
void MarlinUI::status_printf_P(const uint8_t level, PGM_P const fmt, ...) {
if (level < status_message_level) return;
status_message_level = level;
va_list args;
va_start(args, fmt);
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args);
va_end(args);
finishstatus(level > 0);
}
void MarlinUI::setstatusPGM(PGM_P const message, int8_t level) {
if (level < 0) level = status_message_level = 0;
if (level < status_message_level) return;
status_message_level = level;
// Here we have a problem. The message is encoded in UTF8, so
// arbitrarily cutting it will be a problem. We MUST be sure
// that there is no cutting in the middle of a multibyte character!
// Get a pointer to the null terminator
PGM_P pend = message + strlen_P(message);
// If length of supplied UTF8 string is greater than
// our buffer size, start cutting whole UTF8 chars
while ((pend - message) > MAX_MESSAGE_LENGTH) {
--pend;
while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend;
};
// At this point, we have the proper cut point. Use it
uint8_t maxLen = pend - message;
strncpy_P(status_message, message, maxLen);
status_message[maxLen] = '\0';
finishstatus(level > 0);
}
void MarlinUI::setalertstatusPGM(PGM_P const message) {
setstatusPGM(message, 1);
#if HAS_LCD_MENU
return_to_status();
#endif
}
#endif // HAS_SPI_LCD
#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI)
#if ENABLED(EXTENSIBLE_UI)
#include "extensible_ui/ui_api.h"
#endif
////////////////////////////////////////////
/////////////// Status Line ////////////////
////////////////////////////////////////////
void MarlinUI::finishstatus(const bool persist) {
#if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0))
UNUSED(persist);
#endif
#if ENABLED(LCD_PROGRESS_BAR)
progress_bar_ms = millis();
#if PROGRESS_MSG_EXPIRE > 0
expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE;
#endif
#endif
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT)
next_filament_display = millis() + 5000UL; // Show status message for 5s
#endif
#if ENABLED(STATUS_MESSAGE_SCROLLING)
status_scroll_offset = 0;
#endif
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onStatusChanged(status_message);
#endif
refresh();
}
bool MarlinUI::has_status() { return (status_message[0] != '\0'); }
void MarlinUI::set_status(const char * const message, const bool persist) {
if (status_message_level > 0) return;
// Here we have a problem. The message is encoded in UTF8, so
// arbitrarily cutting it will be a problem. We MUST be sure
// that there is no cutting in the middle of a multibyte character!
// Get a pointer to the null terminator
const char* pend = message + strlen(message);
// If length of supplied UTF8 string is greater than
// our buffer size, start cutting whole UTF8 chars
while ((pend - message) > MAX_MESSAGE_LENGTH) {
--pend;
while (!START_OF_UTF8_CHAR(*pend)) --pend;
};
// At this point, we have the proper cut point. Use it
uint8_t maxLen = pend - message;
strncpy(status_message, message, maxLen);
status_message[maxLen] = '\0';
finishstatus(persist);
}
#include <stdarg.h>
void MarlinUI::status_printf_P(const uint8_t level, PGM_P const fmt, ...) {
if (level < status_message_level) return;
status_message_level = level;
va_list args;
va_start(args, fmt);
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args);
va_end(args);
finishstatus(level > 0);
}
void MarlinUI::set_status_P(PGM_P const message, int8_t level) {
if (level < 0) level = status_message_level = 0;
if (level < status_message_level) return;
status_message_level = level;
// Here we have a problem. The message is encoded in UTF8, so
// arbitrarily cutting it will be a problem. We MUST be sure
// that there is no cutting in the middle of a multibyte character!
// Get a pointer to the null terminator
PGM_P pend = message + strlen_P(message);
// If length of supplied UTF8 string is greater than
// our buffer size, start cutting whole UTF8 chars
while ((pend - message) > MAX_MESSAGE_LENGTH) {
--pend;
while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend;
};
// At this point, we have the proper cut point. Use it
uint8_t maxLen = pend - message;
strncpy_P(status_message, message, maxLen);
status_message[maxLen] = '\0';
finishstatus(level > 0);
}
void MarlinUI::set_alert_status_P(PGM_P const message) {
set_status_P(message, 1);
#if HAS_LCD_MENU
return_to_status();
#endif
}
#include "../module/printcounter.h"
/**
@ -1202,14 +1218,14 @@ void MarlinUI::setalertstatusPGM(PGM_P const message) {
msg = paused;
#if ENABLED(SDSUPPORT)
else if (IS_SD_PRINTING())
return setstatus(card.longest_filename(), true);
return set_status(card.longest_filename(), true);
#endif
else if (print_job_timer.isRunning())
msg = printing;
else
msg = welcome;
setstatusPGM(msg, -1);
set_status_P(msg, -1);
}
#endif

View File

@ -243,15 +243,22 @@ public:
#if HAS_SPI_LCD || ENABLED(MALYAN_LCD) || ENABLED(EXTENSIBLE_UI)
static void init();
static void update();
static void setalertstatusPGM(PGM_P message);
static void set_alert_status_P(PGM_P message);
#else // NO LCD
static inline void init() {}
static inline void update() {}
static inline void setalertstatusPGM(PGM_P message) { UNUSED(message); }
static inline void set_alert_status_P(PGM_P message) { UNUSED(message); }
#endif
#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI)
static char status_message[];
static bool has_status();
static uint8_t status_message_level; // Higher levels block lower levels
static inline void reset_alert_level() { status_message_level = 0; }
#if HAS_SPI_LCD
static bool detected();
@ -296,16 +303,10 @@ public:
#endif
// Status message
static char status_message[];
#if ENABLED(STATUS_MESSAGE_SCROLLING)
static uint8_t status_scroll_offset;
#endif
static bool has_status();
static uint8_t lcd_status_update_delay;
static uint8_t status_message_level; // Higher levels block lower levels
static inline void reset_alert_level() { status_message_level = 0; }
#if HAS_PRINT_PROGRESS
#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
@ -341,26 +342,22 @@ public:
static void status_screen();
#else
static void refresh() {}
static inline void reset_alert_level() {}
static constexpr bool has_status() { return true; }
#endif
static bool get_blink();
static void kill_screen(PGM_P const lcd_msg);
static void draw_kill_screen();
static void setstatus(const char* const message, const bool persist=false);
static void setstatusPGM(PGM_P const message, const int8_t level=0);
static void set_status(const char* const message, const bool persist=false);
static void set_status_P(PGM_P const message, const int8_t level=0);
static void status_printf_P(const uint8_t level, PGM_P const fmt, ...);
static void reset_status();
#else // MALYAN_LCD or NO LCD
static inline void refresh() {}
static inline void setstatus(const char* const message, const bool persist=false) { UNUSED(message); UNUSED(persist); }
static inline void setstatusPGM(PGM_P const message, const int8_t level=0) { UNUSED(message); UNUSED(level); }
static inline void set_status(const char* const message, const bool persist=false) { UNUSED(message); UNUSED(persist); }
static inline void set_status_P(PGM_P const message, const int8_t level=0) { UNUSED(message); UNUSED(level); }
static inline void status_printf_P(const uint8_t level, PGM_P const fmt, ...) { UNUSED(level); UNUSED(fmt); }
static inline void reset_status() {}
static inline void reset_alert_level() {}
@ -508,6 +505,10 @@ private:
static void _synchronize();
#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI)
static void finishstatus(const bool persist);
#endif
#if HAS_SPI_LCD
#if HAS_LCD_MENU
#if LCD_TIMEOUT_TO_STATUS
@ -517,13 +518,10 @@ private:
#endif
#endif
static void draw_status_screen();
static void finishstatus(const bool persist);
#else
static inline void finishstatus(const bool persist) { UNUSED(persist); refresh(); }
#endif
};
extern MarlinUI ui;
#define LCD_MESSAGEPGM(x) ui.setstatusPGM(PSTR(x))
#define LCD_ALERTMESSAGEPGM(x) ui.setalertstatusPGM(PSTR(x))
#define LCD_MESSAGEPGM(x) ui.set_status_P(PSTR(x))
#define LCD_ALERTMESSAGEPGM(x) ui.set_alert_status_P(PSTR(x))