update code base to Marlin 2.0.9.2

This commit is contained in:
Stefan Kalscheuer
2021-10-03 18:57:12 +02:00
parent b9d7ba838e
commit 7077da3591
2617 changed files with 332093 additions and 103438 deletions

40
Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp Executable file → Normal file
View File

@@ -1,3 +1,25 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* @file lcdprint_hd44780.cpp
* @brief LCD print api for HD44780
@@ -14,19 +36,15 @@
#include "../../inc/MarlinConfigPre.h"
#if HAS_CHARACTER_LCD
#if HAS_MARLINUI_HD44780
#include "../ultralcd.h"
#include "../marlinui.h"
#include "../../MarlinCore.h"
#include "ultralcd_HD44780.h"
#include "marlinui_HD44780.h"
#include <string.h>
#ifndef LCD_CLASS
#include <LiquidCrystal.h>
#define LCD_CLASS LiquidCrystal
#endif
extern LCD_CLASS lcd;
int lcd_glyph_height() { return 1; }
@@ -678,6 +696,8 @@ static const hd44780_charmap_t g_hd44780_charmap_common[] PROGMEM = {
{IV('ď'), 'd', 0}, // 010F
{IV('đ'), 'd', 0}, // 0111
{IV('ę'), 'e', 0}, // 0119
{IV('Ě'), 'E', 0}, // 011A
{IV('ě'), 'e', 0}, // 011B
{IV('ğ'), 'g', 0}, // 011F
{IV('İ'), 'I', 0}, // 0130
{IV('ı'), 'i', 0}, // 0131
@@ -688,6 +708,7 @@ static const hd44780_charmap_t g_hd44780_charmap_common[] PROGMEM = {
{IV('ń'), 'n', 0}, // 0144
{IV('ň'), 'n', 0}, // 0148
{IV('Ř'), 'R', 0}, // 0158
{IV('ř'), 'r', 0}, // 0159
{IV('Ś'), 'S', 0}, // 015A
{IV('ś'), 's', 0}, // 015B
@@ -924,6 +945,7 @@ static const hd44780_charmap_t g_hd44780_charmap_common[] PROGMEM = {
{IV('ю'), '|', 'o'},
{IV('я'), 'g', 0}, // 044F
{IV('ё'), 'e', 0}, // 0451
#endif
{IV(''), '.', 0}, // 2022 ·
@@ -982,7 +1004,7 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
if (max_length < 1) return 0;
// TODO: fix the '\\' that doesnt exist in the HD44870
// TODO: fix the '\\' that doesn't exist in the HD44870
if (c < 128) {
lcd.write((uint8_t)c);
return 1;
@@ -1119,4 +1141,4 @@ int lcd_put_u8str_max_P(PGM_P utf8_str_P, pixel_len_t max_length) {
#endif // DEBUG_LCDPRINT
#endif // HAS_CHARACTER_LCD
#endif // HAS_MARLINUI_HD44780

View File

@@ -16,23 +16,23 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfigPre.h"
#if HAS_CHARACTER_LCD
#if HAS_MARLINUI_HD44780
/**
* ultralcd_HD44780.cpp
* marlinui_HD44780.cpp
*
* LCD display implementations for Hitachi HD44780.
* These are the most common LCD character displays.
*/
#include "ultralcd_HD44780.h"
#include "../ultralcd.h"
#include "marlinui_HD44780.h"
#include "../marlinui.h"
#include "../../libs/numtostr.h"
#include "../../sd/cardreader.h"
@@ -46,6 +46,14 @@
#include "../../gcode/parser.h"
#endif
#if EITHER(HAS_COOLER, LASER_COOLANT_FLOW_METER)
#include "../../feature/cooler.h"
#endif
#if ENABLED(I2C_AMMETER)
#include "../../feature/ammeter.h"
#endif
#if ENABLED(AUTO_BED_LEVELING_UBL)
#include "../../feature/bedlevel/bedlevel.h"
#endif
@@ -60,11 +68,7 @@
#elif EITHER(LCD_I2C_TYPE_MCP23017, LCD_I2C_TYPE_MCP23008)
LCD_CLASS lcd(LCD_I2C_ADDRESS
#ifdef DETECT_DEVICE
, 1
#endif
);
LCD_CLASS lcd(LCD_I2C_ADDRESS OPTARG(DETECT_I2C_LCD_DEVICE, 1));
#elif ENABLED(LCD_I2C_TYPE_PCA8574)
@@ -93,6 +97,10 @@
LCD_CLASS lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#elif ENABLED(YHCB2004)
LCD_CLASS lcd(YHCB2004_CLK, 20, 4, YHCB2004_MOSI, YHCB2004_MISO); // CLK, cols, rows, MOSI, MISO
#else
// Standard direct-connected LCD implementations
@@ -113,6 +121,7 @@ static void createChar_P(const char c, const byte * const ptr) {
#if ENABLED(LCD_USE_I2C_BUZZER)
void MarlinUI::buzz(const long duration, const uint16_t freq) {
if (!buzzer_enabled) return;
lcd.buzz(duration, freq);
}
#endif
@@ -275,7 +284,7 @@ void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARS
#endif // LCD_PROGRESS_BAR
#if ENABLED(SDSUPPORT) && HAS_LCD_MENU
#if BOTH(SDSUPPORT, HAS_LCD_MENU)
// CHARSET_MENU
const static PROGMEM byte refresh[8] = {
@@ -325,7 +334,7 @@ void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARS
#endif
{
createChar_P(LCD_STR_UPLEVEL[0], uplevel);
#if ENABLED(SDSUPPORT) && HAS_LCD_MENU
#if BOTH(SDSUPPORT, HAS_LCD_MENU)
// SD Card sub-menu special characters
createChar_P(LCD_STR_REFRESH[0], refresh);
createChar_P(LCD_STR_FOLDER[0], folder);
@@ -367,11 +376,7 @@ void MarlinUI::init_lcd() {
}
bool MarlinUI::detected() {
return true
#if EITHER(LCD_I2C_TYPE_MCP23017, LCD_I2C_TYPE_MCP23008) && defined(DETECT_DEVICE)
&& lcd.LcdDetected() == 1
#endif
;
return TERN1(DETECT_I2C_LCD_DEVICE, lcd.LcdDetected() == 1);
}
#if HAS_SLOW_BUTTONS
@@ -470,7 +475,6 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
// Show the Marlin logo and short build version
// After a delay show the website URL
//
extern const char NUL_STR[];
logo_lines(NUL_STR);
CENTER_OR_SCROLL(SHORT_BUILD_VERSION, 1500);
CENTER_OR_SCROLL(MARLIN_WEBSITE_URL, 1500);
@@ -478,7 +482,9 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
CENTER_OR_SCROLL(STRING_SPLASH_LINE3, 1500);
#endif
}
}
void MarlinUI::bootscreen_completion(const millis_t) {
lcd.clear();
safe_delay(100);
set_custom_characters(CHARSET_INFO);
@@ -505,52 +511,40 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
lcd_put_wchar('X' + uint8_t(axis));
if (blink)
lcd_put_u8str(value);
else {
if (!TEST(axis_homed, axis))
while (const char c = *value++) lcd_put_wchar(c <= '.' ? c : '?');
else {
#if NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING)
if (!TEST(axis_known_position, axis))
lcd_put_u8str_P(axis == Z_AXIS ? PSTR(" ") : PSTR(" "));
else
#endif
lcd_put_u8str(value);
}
}
else if (axis_should_home(axis))
while (const char c = *value++) lcd_put_wchar(c <= '.' ? c : '?');
else if (NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING) && !axis_is_trusted(axis))
lcd_put_u8str_P(axis == Z_AXIS ? PSTR(" ") : PSTR(" "));
else
lcd_put_u8str(value);
}
FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const char prefix, const bool blink) {
FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char prefix, const bool blink) {
#if HAS_HEATED_BED
const bool isBed = heater < 0;
const float t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater)),
t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater));
const bool isBed = TERN(HAS_HEATED_CHAMBER, heater_id == H_BED, heater_id < 0);
const celsius_t t1 = (isBed ? thermalManager.wholeDegBed() : thermalManager.wholeDegHotend(heater_id)),
t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater_id));
#else
const float t1 = thermalManager.degHotend(heater), t2 = thermalManager.degTargetHotend(heater);
const celsius_t t1 = thermalManager.wholeDegHotend(heater_id), t2 = thermalManager.degTargetHotend(heater_id);
#endif
if (prefix >= 0) lcd_put_wchar(prefix);
lcd_put_u8str(i16tostr3rj(t1 + 0.5));
lcd_put_u8str(t1 < 0 ? "err" : i16tostr3rj(t1));
lcd_put_wchar('/');
#if !HEATER_IDLE_HANDLER
UNUSED(blink);
#else
const bool is_idle = (
#if HAS_HEATED_BED
isBed ? thermalManager.bed_idle.timed_out :
#endif
thermalManager.hotend_idle[heater].timed_out
);
if (!blink && is_idle) {
if (!blink && thermalManager.heater_idle[thermalManager.idle_index_for_id(heater_id)].timed_out) {
lcd_put_wchar(' ');
if (t2 >= 10) lcd_put_wchar(' ');
if (t2 >= 100) lcd_put_wchar(' ');
}
else
#endif
lcd_put_u8str(i16tostr3left(t2 + 0.5));
lcd_put_u8str(i16tostr3left(t2));
if (prefix >= 0) {
lcd_put_wchar(LCD_STR_DEGREE[0]);
@@ -559,28 +553,67 @@ FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const char pref
}
}
#if HAS_COOLER
FORCE_INLINE void _draw_cooler_status(const char prefix, const bool blink) {
const celsius_t t2 = thermalManager.degTargetCooler();
if (prefix >= 0) lcd_put_wchar(prefix);
lcd_put_u8str(i16tostr3rj(thermalManager.wholeDegCooler()));
lcd_put_wchar('/');
#if !HEATER_IDLE_HANDLER
UNUSED(blink);
#else
if (!blink && thermalManager.heater_idle[thermalManager.idle_index_for_id(heater_id)].timed_out) {
lcd_put_wchar(' ');
if (t2 >= 10) lcd_put_wchar(' ');
if (t2 >= 100) lcd_put_wchar(' ');
}
else
#endif
lcd_put_u8str(i16tostr3left(t2));
if (prefix >= 0) {
lcd_put_wchar(LCD_STR_DEGREE[0]);
lcd_put_wchar(' ');
if (t2 < 10) lcd_put_wchar(' ');
}
}
#endif
#if ENABLED(LASER_COOLANT_FLOW_METER)
FORCE_INLINE void _draw_flowmeter_status() {
lcd_put_u8str("~");
lcd_put_u8str(ftostr11ns(cooler.flowrate));
lcd_put_wchar('L');
}
#endif
#if ENABLED(I2C_AMMETER)
FORCE_INLINE void _draw_ammeter_status() {
lcd_put_u8str(" ");
ammeter.read();
if (ammeter.current <= 0.999f) {
lcd_put_u8str(ui16tostr3rj(uint16_t(ammeter.current * 1000 + 0.5f)));
lcd_put_u8str("mA");
}
else {
lcd_put_u8str(ftostr12ns(ammeter.current));
lcd_put_wchar('A');
}
}
#endif
FORCE_INLINE void _draw_bed_status(const bool blink) {
_draw_heater_status(H_BED, (
#if HAS_LEVELING
planner.leveling_active && blink ? '_' :
#endif
LCD_STR_BEDTEMP[0]
),
blink
);
_draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink);
}
#if HAS_PRINT_PROGRESS
FORCE_INLINE void _draw_print_progress() {
const uint8_t progress = ui.get_progress_percent();
lcd_put_u8str_P(PSTR(
#if ENABLED(SDSUPPORT)
"SD"
#elif ENABLED(LCD_SET_PROGRESS_MANUALLY)
"P:"
#endif
));
lcd_put_u8str_P(PSTR(TERN(SDSUPPORT, "SD", "P:")));
if (progress)
lcd_put_u8str(ui8tostr3rj(progress));
else
@@ -593,9 +626,9 @@ FORCE_INLINE void _draw_bed_status(const bool blink) {
#if ENABLED(LCD_PROGRESS_BAR)
void MarlinUI::draw_progress_bar(const uint8_t percent) {
const int16_t tix = (int16_t)(percent * (LCD_WIDTH) * 3) / 100,
cel = tix / 3,
rem = tix % 3;
const int16_t tix = int16_t(percent * (LCD_WIDTH) * 3) / 100,
cel = tix / 3,
rem = tix % 3;
uint8_t i = LCD_WIDTH;
char msg[LCD_WIDTH + 1], b = ' ';
msg[LCD_WIDTH] = '\0';
@@ -664,12 +697,15 @@ void MarlinUI::draw_status_message(const bool blink) {
// If the remaining string doesn't completely fill the screen
if (rlen < LCD_WIDTH) {
lcd_put_wchar('.'); // Always at 1+ spaces left, draw a dot
uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters
if (--chars) { // Draw a second dot if there's space
lcd_put_wchar('.');
if (--chars)
lcd_put_u8str_max(status_message, chars); // Print a second copy of the message
lcd_put_wchar(' '); // Always at 1+ spaces left, draw a space
if (--chars) { // Draw a second space if there's room
lcd_put_wchar(' ');
if (--chars) { // Draw a third space if there's room
lcd_put_wchar(' ');
if (--chars)
lcd_put_u8str_max(status_message, chars); // Print a second copy of the message
}
}
}
if (last_blink != blink) {
@@ -726,6 +762,35 @@ void MarlinUI::draw_status_message(const bool blink) {
* |01234567890123456789|
*/
inline uint8_t draw_elapsed_or_remaining_time(uint8_t timepos, const bool blink) {
char buffer[14];
#if ENABLED(SHOW_REMAINING_TIME)
const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && printingIsActive();
if (show_remain) {
#if ENABLED(USE_M73_REMAINING_TIME)
duration_t remaining = ui.get_remaining_time();
#else
uint8_t progress = ui.get_progress_percent();
uint32_t elapsed = print_job_timer.duration();
duration_t remaining = (progress > 0) ? ((elapsed * 25600 / progress) >> 8) - elapsed : 0;
#endif
timepos -= remaining.toDigital(buffer);
lcd_put_wchar(timepos, 2, 'R');
}
#else
constexpr bool show_remain = false;
#endif
if (!show_remain) {
duration_t elapsed = print_job_timer.duration();
timepos -= elapsed.toDigital(buffer);
lcd_put_wchar(timepos, 2, LCD_STR_CLOCK[0]);
}
lcd_put_u8str(buffer);
return timepos;
}
void MarlinUI::draw_status_screen() {
const bool blink = get_blink();
@@ -740,17 +805,19 @@ void MarlinUI::draw_status_screen() {
//
// Hotend 0 Temperature
//
_draw_heater_status(H_E0, -1, blink);
#if HAS_HOTEND
_draw_heater_status(H_E0, -1, blink);
//
// Hotend 1 or Bed Temperature
//
#if HOTENDS > 1
lcd_moveto(8, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(8, 0);
_draw_bed_status(blink);
//
// Hotend 1 or Bed Temperature
//
#if HAS_MULTI_HOTEND
lcd_moveto(8, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(8, 0);
_draw_bed_status(blink);
#endif
#endif
#else // LCD_WIDTH >= 20
@@ -758,19 +825,25 @@ void MarlinUI::draw_status_screen() {
//
// Hotend 0 Temperature
//
_draw_heater_status(H_E0, LCD_STR_THERMOMETER[0], blink);
#if HAS_HOTEND
_draw_heater_status(H_E0, LCD_STR_THERMOMETER[0], blink);
//
// Hotend 1 or Bed Temperature
//
#if HOTENDS > 1
lcd_moveto(10, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(10, 0);
_draw_bed_status(blink);
//
// Hotend 1 or Bed Temperature
//
#if HAS_MULTI_HOTEND
lcd_moveto(10, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(10, 0);
_draw_bed_status(blink);
#endif
#endif
TERN_(HAS_COOLER, _draw_cooler_status('*', blink));
TERN_(LASER_COOLANT_FLOW_METER, _draw_flowmeter_status());
TERN_(I2C_AMMETER, _draw_ammeter_status());
#endif // LCD_WIDTH >= 20
// ========== Line 2 ==========
@@ -791,7 +864,7 @@ void MarlinUI::draw_status_screen() {
// If the first line has two extruder temps,
// show more temperatures on the next line
#if HOTENDS > 2 || (HOTENDS > 1 && HAS_HEATED_BED)
#if HOTENDS > 2 || (HAS_MULTI_HOTEND && HAS_HEATED_BED)
#if HOTENDS > 2
_draw_heater_status(H_E2, LCD_STR_THERMOMETER[0], blink);
@@ -802,7 +875,7 @@ void MarlinUI::draw_status_screen() {
#else // HOTENDS <= 2 && (HOTENDS <= 1 || !HAS_HEATED_BED)
#if DUAL_MIXING_EXTRUDER
#if HAS_DUAL_MIXING
// Two-component mix / gradient instead of XY
@@ -822,19 +895,11 @@ void MarlinUI::draw_status_screen() {
sprintf_P(mixer_messages, PSTR("%s %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1]));
lcd_put_u8str(mixer_messages);
#else // !DUAL_MIXING_EXTRUDER
#else // !HAS_DUAL_MIXING
if (true
#if ENABLED(LCD_SHOW_E_TOTAL)
&& !printingIsActive()
#endif
) {
const xy_pos_t lpos = current_position.asLogical();
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink);
lcd_put_wchar(' ');
_draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink);
}
else {
const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
if (show_e_total) {
#if ENABLED(LCD_SHOW_E_TOTAL)
char tmp[20];
const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // After 100m switch to cm
@@ -842,8 +907,14 @@ void MarlinUI::draw_status_screen() {
lcd_put_u8str(tmp);
#endif
}
else {
const xy_pos_t lpos = current_position.asLogical();
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink);
lcd_put_wchar(' ');
_draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink);
}
#endif // !DUAL_MIXING_EXTRUDER
#endif // !HAS_DUAL_MIXING
#endif // HOTENDS <= 2 && (HOTENDS <= 1 || !HAS_HEATED_BED)
@@ -866,12 +937,7 @@ void MarlinUI::draw_status_screen() {
lcd_put_u8str(i16tostr3rj(feedrate_percentage));
lcd_put_wchar('%');
char buffer[14];
duration_t elapsed = print_job_timer.duration();
const uint8_t len = elapsed.toDigital(buffer),
timepos = LCD_WIDTH - len - 1;
lcd_put_wchar(timepos, 2, LCD_STR_CLOCK[0]);
lcd_put_u8str(buffer);
const uint8_t timepos = draw_elapsed_or_remaining_time(LCD_WIDTH - 1, blink);
#if LCD_WIDTH >= 20
lcd_moveto(timepos - 7, 2);
@@ -891,12 +957,12 @@ void MarlinUI::draw_status_screen() {
#if ENABLED(ADAPTIVE_FAN_SLOWING)
else { c = '*'; spd = thermalManager.scaledFanSpeed(0, spd); }
#endif
per = thermalManager.fanPercent(spd);
per = thermalManager.pwmToPercent(spd);
}
else
#endif
{
#if EXTRUDERS
#if HAS_EXTRUDERS
c = 'E';
per = planner.flow_percentage[0];
#endif
@@ -924,7 +990,7 @@ void MarlinUI::draw_status_screen() {
lcd_moveto(LCD_WIDTH - 9, 0);
_draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position.z)), blink);
#if HAS_LEVELING && (HOTENDS > 1 || !HAS_HEATED_BED)
#if HAS_LEVELING && (HAS_MULTI_HOTEND || !HAS_HEATED_BED)
lcd_put_wchar(LCD_WIDTH - 1, 0, planner.leveling_active || blink ? '_' : ' ');
#endif
@@ -934,7 +1000,7 @@ void MarlinUI::draw_status_screen() {
// Hotend 1 or Bed Temperature
//
lcd_moveto(0, 1);
#if HOTENDS > 1
#if HAS_MULTI_HOTEND
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
_draw_bed_status(blink);
@@ -952,10 +1018,10 @@ void MarlinUI::draw_status_screen() {
lcd_moveto(0, 2);
#if HOTENDS > 2
_draw_heater_status(H_E2, LCD_STR_THERMOMETER[0], blink);
#elif HOTENDS > 1 && HAS_HEATED_BED
#elif HAS_MULTI_HOTEND && HAS_HEATED_BED
_draw_bed_status(blink);
#elif HAS_PRINT_PROGRESS
#define DREW_PRINT_PROGRESS
#define DREW_PRINT_PROGRESS 1
_draw_print_progress();
#endif
@@ -963,14 +1029,15 @@ void MarlinUI::draw_status_screen() {
// Elapsed Time or SD Percent
//
lcd_moveto(LCD_WIDTH - 9, 2);
#if HAS_PRINT_PROGRESS && !defined(DREW_PRINT_PROGRESS)
#if HAS_PRINT_PROGRESS && !DREW_PRINT_PROGRESS
_draw_print_progress();
#else
duration_t elapsed = print_job_timer.duration();
char buffer[14];
(void)elapsed.toDigital(buffer);
lcd_put_wchar(LCD_STR_CLOCK[0]);
lcd_put_u8str(buffer);
(void)draw_elapsed_or_remaining_time(LCD_WIDTH - 4, blink);
#endif
#endif // LCD_INFO_SCREEN_STYLE 1
@@ -992,55 +1059,56 @@ void MarlinUI::draw_status_screen() {
void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) {
if (row < LCD_HEIGHT) {
lcd_moveto(LCD_WIDTH - 9, row);
_draw_heater_status((heater_ind_t)extruder, LCD_STR_THERMOMETER[0], get_blink());
_draw_heater_status((heater_id_t)extruder, LCD_STR_THERMOMETER[0], get_blink());
}
}
#endif // ADVANCED_PAUSE_FEATURE
// Draw a static item with no left-right margin required. Centered by default.
void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
int8_t n = LCD_WIDTH;
lcd_moveto(0, row);
if ((style & SS_CENTER) && !valstr) {
int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
if (style & SS_CENTER) {
int8_t pad = (LCD_WIDTH - plen - vlen) / 2;
while (--pad >= 0) { lcd_put_wchar(' '); n--; }
}
n = lcd_put_u8str_ind_P(pstr, itemIndex, n);
if (valstr) n -= lcd_put_u8str_max(valstr, n);
if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n);
if (vlen) n -= lcd_put_u8str_max(vstr, n);
for (; n > 0; --n) lcd_put_wchar(' ');
}
// Draw a generic menu item with pre_char (if selected) and post_char
void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) {
lcd_put_wchar(0, row, sel ? pre_char : ' ');
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2);
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2);
for (; n; --n) lcd_put_wchar(' ');
lcd_put_wchar(post_char);
}
// Draw a menu item with a (potentially) editable value
void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
const uint8_t vlen = data ? (pgm ? utf8_strlen_P(data) : utf8_strlen(data)) : 0;
void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const inStr, const bool pgm) {
const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0;
lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2 - vlen);
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen);
if (vlen) {
lcd_put_wchar(':');
for (; n; --n) lcd_put_wchar(' ');
if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data);
if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr);
}
}
// Low-level draw_edit_screen can be used to draw an edit screen from anyplace
void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) {
ui.encoder_direction_normal();
uint8_t n = lcd_put_u8str_ind_P(0, 1, pstr, itemIndex, LCD_WIDTH - 1);
if (value != nullptr) {
lcd_put_wchar(':');
int len = utf8_strlen(value);
const lcd_uint_t valrow = (n < len + 1) ? 2 : 1; // Value on the next row if it won't fit
lcd_put_wchar((LCD_WIDTH - 1) - (len + 1), valrow, ' '); // Right-justified, padded, leading space
uint8_t n = lcd_put_u8str_ind_P(0, 1, pstr, itemIndex, itemString, LCD_WIDTH - 1);
if (value) {
lcd_put_wchar(':'); n--;
const uint8_t len = utf8_strlen(value) + 1; // Plus one for a leading space
const lcd_uint_t valrow = n < len ? 2 : 1; // Value on the next row if it won't fit
lcd_put_wchar(LCD_WIDTH - len, valrow, ' '); // Right-justified, padded, leading space
lcd_put_u8str(value);
}
}
@@ -1073,46 +1141,22 @@ void MarlinUI::draw_status_screen() {
static uint8_t ledsprev = 0;
uint8_t leds = 0;
#if HAS_HEATED_BED
if (thermalManager.degTargetBed() > 0) leds |= LED_A;
#endif
if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0)) leds |= LED_A;
if (TERN0(HAS_HOTEND, thermalManager.degTargetHotend(0) > 0)) leds |= LED_B;
#if HOTENDS
if (thermalManager.degTargetHotend(0) > 0) leds |= LED_B;
#endif
#if FAN_COUNT > 0
if (0
#if HAS_FAN0
|| thermalManager.fan_speed[0]
#endif
#if HAS_FAN1
|| thermalManager.fan_speed[1]
#endif
#if HAS_FAN2
|| thermalManager.fan_speed[2]
#endif
#if HAS_FAN3
|| thermalManager.fan_speed[3]
#endif
#if HAS_FAN4
|| thermalManager.fan_speed[4]
#endif
#if HAS_FAN5
|| thermalManager.fan_speed[5]
#endif
#if HAS_FAN6
|| thermalManager.fan_speed[6]
#endif
#if HAS_FAN7
|| thermalManager.fan_speed[7]
#endif
#if HAS_FAN
if ( TERN0(HAS_FAN0, thermalManager.fan_speed[0])
|| TERN0(HAS_FAN1, thermalManager.fan_speed[1])
|| TERN0(HAS_FAN2, thermalManager.fan_speed[2])
|| TERN0(HAS_FAN3, thermalManager.fan_speed[3])
|| TERN0(HAS_FAN4, thermalManager.fan_speed[4])
|| TERN0(HAS_FAN5, thermalManager.fan_speed[5])
|| TERN0(HAS_FAN6, thermalManager.fan_speed[6])
|| TERN0(HAS_FAN7, thermalManager.fan_speed[7])
) leds |= LED_C;
#endif // FAN_COUNT > 0
#endif // HAS_FAN
#if HOTENDS > 1
if (thermalManager.degTargetHotend(1) > 0) leds |= LED_C;
#endif
if (TERN0(HAS_MULTI_HOTEND, thermalManager.degTargetHotend(1) > 0)) leds |= LED_C;
if (leds != ledsprev) {
lcd.setBacklight(leds);
@@ -1248,7 +1292,7 @@ void MarlinUI::draw_status_screen() {
pixels_per_x_mesh_pnt, pixels_per_y_mesh_pnt,
suppress_x_offset = 0, suppress_y_offset = 0;
const uint8_t y_plot_inv = (GRID_MAX_POINTS_Y - 1) - y_plot;
const uint8_t y_plot_inv = (GRID_MAX_POINTS_Y) - 1 - y_plot;
upper_left.column = 0;
upper_left.row = 0;
@@ -1277,7 +1321,7 @@ void MarlinUI::draw_status_screen() {
y_map_pixels = pixels_per_y_mesh_pnt * (GRID_MAX_POINTS_Y); // Directions fit nicely
right_edge = pixels_per_x_mesh_pnt * (GRID_MAX_POINTS_X) + 1; // Find location of right edge within the character cell
bottom_line = pixels_per_y_mesh_pnt * (GRID_MAX_POINTS_Y) + 1; // Find location of bottome line within the character cell
bottom_line = pixels_per_y_mesh_pnt * (GRID_MAX_POINTS_Y) + 1; // Find location of bottom line within the character cell
n_rows = bottom_line / (HD44780_CHAR_HEIGHT) + 1;
n_cols = right_edge / (HD44780_CHAR_WIDTH) + 1;
@@ -1541,4 +1585,4 @@ void MarlinUI::draw_status_screen() {
#endif // HAS_LCD_MENU
#endif // HAS_CHARACTER_LCD
#endif // HAS_MARLINUI_HD44780

View File

@@ -16,32 +16,19 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Implementation of the LCD display routines for a Hitachi HD44780 display.
* These are the most common LCD character displays.
* Hitachi HD44780 display defines and headers
*/
#include "../../inc/MarlinConfig.h"
#if LCD_HEIGHT > 3
#include "../../libs/duration_t.h"
#endif
////////////////////////////////////
// Setup button and encode mappings for each panel (into 'buttons' variable
//
// This is just to map common functions (across different panels) onto the same
// macro name. The mapping is independent of whether the button is directly connected or
// via a shift/i2c register.
////////////////////////////////////
// Create LCD class instance and chipset-specific information
#if ENABLED(LCD_I2C_TYPE_PCF8575)
// NOTE: These are register-mapped pins on the PCF8575 controller, not Arduino pins.
#define LCD_I2C_PIN_BL 3
#define LCD_I2C_PIN_EN 2
@@ -58,6 +45,7 @@
#define LCD_CLASS LiquidCrystal_I2C
#elif ENABLED(LCD_I2C_TYPE_MCP23017)
// For the LED indicators (which may be mapped to different events in update_indicators())
#define LCD_HAS_STATUS_INDICATORS
#define LED_A 0x04 //100
@@ -69,40 +57,50 @@
#define LCD_CLASS LiquidTWI2
#elif ENABLED(LCD_I2C_TYPE_MCP23008)
#include <Wire.h>
#include <LiquidTWI2.h>
#define LCD_CLASS LiquidTWI2
#elif ENABLED(LCD_I2C_TYPE_PCA8574)
#include <LiquidCrystal_I2C.h>
#define LCD_CLASS LiquidCrystal_I2C
#elif ENABLED(SR_LCD_2W_NL)
// 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
// extern "C" void __cxa_pure_virtual() { while (1); }
#include <LCD.h>
#include <LiquidCrystal_SR.h>
#define LCD_CLASS LiquidCrystal_SR
#elif ENABLED(SR_LCD_3W_NL)
//NewLiquidCrystal was not working for me, but this worked first try
//https://github.com/mikeshub/SailfishLCD
//uses the code directly from Sailfish
// NewLiquidCrystal didn't work, so this uses
// https://github.com/mikeshub/SailfishLCD
#include <SailfishLCD.h>
#define LCD_CLASS LiquidCrystalSerial
#elif ENABLED(LCM1602)
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define LCD_CLASS LiquidCrystal_I2C
#elif ENABLED(YHCB2004)
#include <LiquidCrystal_AIP31068_SPI.h>
#define LCD_CLASS LiquidCrystal_AIP31068_SPI
#else
// Standard directly connected LCD implementations
#include <LiquidCrystal.h>
#define LCD_CLASS LiquidCrystal
#endif
#include "../fontutils.h"