Skip to content

Commit

Permalink
Use u8g2 for LCD and enable SW i2c
Browse files Browse the repository at this point in the history
  • Loading branch information
dbuezas committed Nov 18, 2023
1 parent b8da82f commit 0cd260a
Show file tree
Hide file tree
Showing 6 changed files with 3,392 additions and 195 deletions.
3 changes: 3 additions & 0 deletions Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -3569,3 +3569,6 @@

// Disable servo with M282 to reduce power consumption, noise, and heat when not in use
//#define SERVO_DETACH_GCODE

#define I2C_SDA_PIN_LCD EXP1_04_PIN
#define I2C_SCL_PIN_LCD EXP1_06_PIN
66 changes: 48 additions & 18 deletions Marlin/src/lcd/dogm/lcdprint_u8g.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,43 +19,73 @@
#include "u8g_fontutf8.h"
#include "../lcdprint.h"

int lcd_glyph_height() { return u8g_GetFontBBXHeight(u8g.getU8g()); }
int lcd_glyph_height() {
// Ascent is the distance from the baseline to the top of the glyph
int fontAscent = u8g.getFontAscent();

// Descent is the distance from the baseline to the bottom of the glyph,
// it is returned as a negative value so we subtract it to get the total height
int fontDescent = u8g.getFontDescent();

// The total glyph height is the ascent minus the descent (which is negative)
return fontAscent - fontDescent;
}

void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) { u8g.setPrintPos(col, row); }
void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) { u8g.setCursor(col, row); }

void lcd_put_int(const int i) { u8g.print(i); }

// return < 0 on error
// return the number of pixels advanced
int lcd_put_lchar_max(const lchar_t &c, const pixel_len_t max_length) {
if (c < 256) {
u8g.print((char)c);
return u8g_GetFontBBXWidth(u8g.getU8g());
void unicodeToUtf8(const uint32_t &c, char *utf8) {
if (c <= 0x7F) {
// ASCII
utf8[0] = c;
utf8[1] = '\0';
} else if (c <= 0x7FF) {
// Two-byte sequence
utf8[0] = 0xC0 | ((c >> 6) & 0x1F);
utf8[1] = 0x80 | (c & 0x3F);
utf8[2] = '\0';
} else if (c <= 0xFFFF) {
// Three-byte sequence
utf8[0] = 0xE0 | ((c >> 12) & 0x0F);
utf8[1] = 0x80 | ((c >> 6) & 0x3F);
utf8[2] = 0x80 | (c & 0x3F);
utf8[3] = '\0';
} else if (c <= 0x10FFFF) {
// Four-byte sequence
utf8[0] = 0xF0 | ((c >> 18) & 0x07);
utf8[1] = 0x80 | ((c >> 12) & 0x3F);
utf8[2] = 0x80 | ((c >> 6) & 0x3F);
utf8[3] = 0x80 | (c & 0x3F);
utf8[4] = '\0';
}
u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
ret = uxg_DrawLchar(u8g.getU8g(), x, y, c, max_length);
u8g.setPrintPos(x + ret, y);
return ret;
}

int lcd_put_lchar_max(const lchar_t &c, const pixel_len_t max_length) {
char utf8[5];
unicodeToUtf8(c, utf8);
u8g.print(utf8);
return u8g.getUTF8Width(utf8); // Get the width of the single character
}

/**
* @return output width in pixels
*/
int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
ret = uxg_DrawUtf8Str(u8g.getU8g(), x, y, utf8_str, max_length);
u8g.setPrintPos(x + ret, y);
return ret;
int initialX = u8g.getCursorX();
u8g.print(utf8_str); // U8g2 handles UTF-8 natively
int width = u8g.getCursorX() - initialX; // Calculate the width of the printed string
return width; // Return the width of the string that was printed
}

/**
* @return output width in pixels
*/
int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
ret = uxg_DrawUtf8StrP(u8g.getU8g(), x, y, utf8_pstr, max_length);
u8g.setPrintPos(x + ret, y);
return ret;
return lcd_put_u8str_max(utf8_pstr, max_length);
}


#endif // HAS_MARLINUI_U8GLIB
34 changes: 16 additions & 18 deletions Marlin/src/lcd/dogm/marlinui_DOGM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@
#else
#define FONT_STATUSMENU_NAME MENU_FONT_NAME
#endif
#include "U8g2lib.h"

U8G_CLASS u8g;
U8G_CLASS u8g(U8G2_R0, I2C_SCL_PIN_LCD, I2C_SDA_PIN_LCD, LCD_RESET_PIN);

#include LANGUAGE_DATA_INCL(LCD_LANGUAGE)
#ifdef LCD_LANGUAGE_2
Expand All @@ -99,10 +100,12 @@ void MarlinUI::set_font(const MarlinFont font_nr) {
static char currentfont = 0;
if (font_nr != currentfont) {
switch ((currentfont = font_nr)) {
case FONT_STATUSMENU : u8g.setFont(FONT_STATUSMENU_NAME); break;
case FONT_EDIT : u8g.setFont(EDIT_FONT_NAME); break;
case FONT_STATUSMENU : u8g.setFont(u8g2_font_profont11_tf); break;
//u8g2_font_spleen5x8_mf
case FONT_EDIT : u8g.setFont(u8g2_font_profont11_tf); break;
default:
case FONT_MENU : u8g.setFont(MENU_FONT_NAME); break;
case FONT_MENU : u8g.setFont(u8g2_font_profont11_tf); break;
//u8g2_font_spleen6x12_mf
}
}
}
Expand Down Expand Up @@ -214,7 +217,7 @@ bool MarlinUI::detected() { return true; }
NOLESS(offy, 0);

auto _draw_bootscreen_bmp = [&](const uint8_t *bitmap) {
u8g.drawBitmapP(offx, offy, START_BMP_BYTEWIDTH, START_BMPHEIGHT, bitmap);
u8g.drawBitmap(offx, offy, START_BMP_BYTEWIDTH, START_BMPHEIGHT, bitmap);
set_font(FONT_MENU);
if (!two_part || !line2) lcd_put_u8str(txt_offx_1, txt_base - (MENU_FONT_HEIGHT), F(SHORT_BUILD_VERSION));
if (!two_part || line2) lcd_put_u8str(txt_offx_2, txt_base, F(MARLIN_WEBSITE_URL));
Expand Down Expand Up @@ -260,13 +263,6 @@ bool MarlinUI::detected() { return true; }

// Initialize or re-initialize the LCD
void MarlinUI::init_lcd() {

static bool did_init_u8g = false;
if (!did_init_u8g) {
u8g.init(U8G_PARAM);
did_init_u8g = true;
}

#if PIN_EXISTS(LCD_BACKLIGHT)
OUT_WRITE(LCD_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT)); // Illuminate after reset or right away
#endif
Expand All @@ -280,12 +276,14 @@ void MarlinUI::init_lcd() {

#if PIN_EXISTS(LCD_RESET)
// Perform a clean hardware reset with needed delays
OUT_WRITE(LCD_RESET_PIN, LOW);
hal.delay_ms(5);
WRITE(LCD_RESET_PIN, HIGH);
hal.delay_ms(5);
u8g.begin();
// OUT_WRITE(LCD_RESET_PIN, LOW);
// hal.delay_ms(5);
// WRITE(LCD_RESET_PIN, HIGH);
// hal.delay_ms(5);
#endif
u8g.setBusClock(400000);
u8g.begin();
u8g.enableUTF8Print();

#if PIN_EXISTS(LCD_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT)
WRITE(LCD_BACKLIGHT_PIN, HIGH);
Expand Down Expand Up @@ -473,7 +471,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
if (!mark_as_selected(row, sel)) return;

const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)),
pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), inStr));
pixelwidth = u8g.getStrWidth(inStr);// (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), inStr));
const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1;

uint8_t n = LCD_WIDTH - 2 - vallen * prop;
Expand Down
18 changes: 13 additions & 5 deletions Marlin/src/lcd/dogm/marlinui_DOGM.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

#include <U8glib-HAL.h>
#include "HAL_LCD_class_defines.h"

#include "U8g2lib.h"
//#define ALTERNATIVE_LCD

#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
Expand Down Expand Up @@ -190,7 +190,7 @@

// Generic support for SSD1309 OLED I2C LCDs

#define U8G_CLASS U8GLIB_SSD1309_128X64
#define U8G_CLASS U8G2_SSD1309_128X64_NONAME0_F_SW_I2C
#define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // I2C

#elif ENABLED(U8GLIB_SSD1306)
Expand Down Expand Up @@ -235,8 +235,16 @@
#endif

// For selective rendering within a Y range
#define PAGE_OVER(ya) ((ya) <= u8g.getU8g()->current_page.y1) // Does the current page follow a region top?
#define PAGE_UNDER(yb) ((yb) >= u8g.getU8g()->current_page.y0) // Does the current page precede a region bottom?
#define PAGE_CONTAINS(ya, yb) ((yb) >= u8g.getU8g()->current_page.y0 && (ya) <= u8g.getU8g()->current_page.y1) // Do two vertical regions overlap?
// #define PAGE_OVER(ya) ((ya) <= u8g.getU8g2()->current_page.y1) // Does the current page follow a region top?
// #define PAGE_UNDER(yb) ((yb) >= u8g.getU8g2()->current_page.y0) // Does the current page precede a region bottom?
// #define PAGE_CONTAINS(ya, yb) ((yb) >= u8g.getU8g2()->current_page.y0 && (ya) <= u8g.getU8g2()->current_page.y1) // Do two vertical regions overlap?

// #define PAGE_OVER(ya) ((ya) < (u8g.getBufferCurrTileRow() + 1) * u8g.getBufferTileHeight()) // Does the current page follow a region top?
// #define PAGE_UNDER(yb) ((yb) >= u8g.getBufferCurrTileRow() * u8g.getBufferTileHeight()) // Does the current page precede a region bottom?
// #define PAGE_CONTAINS(ya, yb) ((yb) >= (u8g.getBufferCurrTileRow() * u8g.getBufferTileHeight()) && (ya) < ((u8g.getBufferCurrTileRow() + 1) * u8g.getBufferTileHeight())) // Do two vertical regions overlap?

#define PAGE_OVER(ya) true
#define PAGE_UNDER(yb) true
#define PAGE_CONTAINS(ya, yb) true

extern U8G_CLASS u8g;
24 changes: 12 additions & 12 deletions Marlin/src/lcd/dogm/status_screen_DOGM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,15 +303,15 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co
const bool draw_partial = isHeat && tall < BAR_TALL;
if (draw_partial) {
const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall;
u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), false));
u8g.drawBitmapP(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), true) + ph * bw);
u8g.drawBitmap(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), false));
u8g.drawBitmap(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), true) + ph * bw);
}
#else
constexpr bool draw_partial = false;
#endif

if (!draw_partial)
u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), isHeat));
u8g.drawBitmap(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), isHeat));

} // PAGE_CONTAINS

Expand Down Expand Up @@ -603,13 +603,13 @@ void MarlinUI::draw_status_screen() {

#if DO_DRAW_LOGO
if (PAGE_CONTAINS(STATUS_LOGO_Y, STATUS_LOGO_Y + STATUS_LOGO_HEIGHT - 1))
u8g.drawBitmapP(STATUS_LOGO_X, STATUS_LOGO_Y, STATUS_LOGO_BYTEWIDTH, STATUS_LOGO_HEIGHT, status_logo_bmp);
u8g.drawBitmap(STATUS_LOGO_X, STATUS_LOGO_Y, STATUS_LOGO_BYTEWIDTH, STATUS_LOGO_HEIGHT, status_logo_bmp);
#endif

#if STATUS_HEATERS_WIDTH
// Draw all heaters (and maybe the bed) in one go
if (PAGE_CONTAINS(STATUS_HEATERS_Y, STATUS_HEATERS_Y + STATUS_HEATERS_HEIGHT - 1))
u8g.drawBitmapP(STATUS_HEATERS_X, STATUS_HEATERS_Y, STATUS_HEATERS_BYTEWIDTH, STATUS_HEATERS_HEIGHT, status_heaters_bmp);
u8g.drawBitmap(STATUS_HEATERS_X, STATUS_HEATERS_Y, STATUS_HEATERS_BYTEWIDTH, STATUS_HEATERS_HEIGHT, status_heaters_bmp);
#endif

#if DO_DRAW_CUTTER && DISABLED(STATUS_COMBINE_HEATERS)
Expand All @@ -621,7 +621,7 @@ void MarlinUI::draw_status_screen() {
const uint8_t cuttery = STATUS_CUTTER_Y(CUTTER_ALT()),
cutterh = STATUS_CUTTER_HEIGHT(CUTTER_ALT());
if (PAGE_CONTAINS(cuttery, cuttery + cutterh - 1))
u8g.drawBitmapP(STATUS_CUTTER_X, cuttery, STATUS_CUTTER_BYTEWIDTH, cutterh, CUTTER_BITMAP(CUTTER_ALT()));
u8g.drawBitmap(STATUS_CUTTER_X, cuttery, STATUS_CUTTER_BYTEWIDTH, cutterh, CUTTER_BITMAP(CUTTER_ALT()));
#endif

#if DO_DRAW_BED && DISABLED(STATUS_COMBINE_HEATERS)
Expand All @@ -639,7 +639,7 @@ void MarlinUI::draw_status_screen() {
const uint8_t bedy = STATUS_BED_Y(BED_ALT()),
bedh = STATUS_BED_HEIGHT(BED_ALT());
if (PAGE_CONTAINS(bedy, bedy + bedh - 1))
u8g.drawBitmapP(STATUS_BED_X, bedy, STATUS_BED_BYTEWIDTH, bedh, BED_BITMAP(BED_ALT()));
u8g.drawBitmap(STATUS_BED_X, bedy, STATUS_BED_BYTEWIDTH, bedh, BED_BITMAP(BED_ALT()));
#endif

#if DO_DRAW_CHAMBER && DISABLED(STATUS_COMBINE_HEATERS)
Expand All @@ -651,7 +651,7 @@ void MarlinUI::draw_status_screen() {
const uint8_t chambery = STATUS_CHAMBER_Y(CHAMBER_ALT()),
chamberh = STATUS_CHAMBER_HEIGHT(CHAMBER_ALT());
if (PAGE_CONTAINS(chambery, chambery + chamberh - 1))
u8g.drawBitmapP(STATUS_CHAMBER_X, chambery, STATUS_CHAMBER_BYTEWIDTH, chamberh, CHAMBER_BITMAP(CHAMBER_ALT()));
u8g.drawBitmap(STATUS_CHAMBER_X, chambery, STATUS_CHAMBER_BYTEWIDTH, chamberh, CHAMBER_BITMAP(CHAMBER_ALT()));
#endif

const bool blink = ui.get_blink();
Expand All @@ -666,7 +666,7 @@ void MarlinUI::draw_status_screen() {
}
#endif
if (PAGE_CONTAINS(STATUS_FAN_Y, STATUS_FAN_Y + STATUS_FAN_HEIGHT - 1))
u8g.drawBitmapP(STATUS_FAN_X, STATUS_FAN_Y, STATUS_FAN_BYTEWIDTH, STATUS_FAN_HEIGHT,
u8g.drawBitmap(STATUS_FAN_X, STATUS_FAN_Y, STATUS_FAN_BYTEWIDTH, STATUS_FAN_HEIGHT,
#if STATUS_FAN_FRAMES > 2
fan_frame == 1 ? status_fan1_bmp :
fan_frame == 2 ? status_fan2_bmp :
Expand Down Expand Up @@ -708,23 +708,23 @@ void MarlinUI::draw_status_screen() {
const uint8_t coolery = STATUS_COOLER_Y(status_cooler_bmp1),
coolerh = STATUS_COOLER_HEIGHT(status_cooler_bmp1);
if (PAGE_CONTAINS(coolery, coolery + coolerh - 1))
u8g.drawBitmapP(STATUS_COOLER_X, coolery, STATUS_COOLER_BYTEWIDTH, coolerh, blink && cooler.enabled ? status_cooler_bmp2 : status_cooler_bmp1);
u8g.drawBitmap(STATUS_COOLER_X, coolery, STATUS_COOLER_BYTEWIDTH, coolerh, blink && cooler.enabled ? status_cooler_bmp2 : status_cooler_bmp1);
#endif

// Laser Cooler Flow Meter
#if DO_DRAW_FLOWMETER
const uint8_t flowmetery = STATUS_FLOWMETER_Y(status_flowmeter_bmp1),
flowmeterh = STATUS_FLOWMETER_HEIGHT(status_flowmeter_bmp1);
if (PAGE_CONTAINS(flowmetery, flowmetery + flowmeterh - 1))
u8g.drawBitmapP(STATUS_FLOWMETER_X, flowmetery, STATUS_FLOWMETER_BYTEWIDTH, flowmeterh, blink && cooler.flowpulses ? status_flowmeter_bmp2 : status_flowmeter_bmp1);
u8g.drawBitmap(STATUS_FLOWMETER_X, flowmetery, STATUS_FLOWMETER_BYTEWIDTH, flowmeterh, blink && cooler.flowpulses ? status_flowmeter_bmp2 : status_flowmeter_bmp1);
#endif

// Laser Ammeter
#if DO_DRAW_AMMETER
const uint8_t ammetery = STATUS_AMMETER_Y(status_ammeter_bmp_mA),
ammeterh = STATUS_AMMETER_HEIGHT(status_ammeter_bmp_mA);
if (PAGE_CONTAINS(ammetery, ammetery + ammeterh - 1))
u8g.drawBitmapP(STATUS_AMMETER_X, ammetery, STATUS_AMMETER_BYTEWIDTH, ammeterh, (ammeter.current < 0.1f) ? status_ammeter_bmp_mA : status_ammeter_bmp_A);
u8g.drawBitmap(STATUS_AMMETER_X, ammetery, STATUS_AMMETER_BYTEWIDTH, ammeterh, (ammeter.current < 0.1f) ? status_ammeter_bmp_mA : status_ammeter_bmp_A);
#endif

// Heated Bed
Expand Down
Loading

0 comments on commit 0cd260a

Please sign in to comment.