diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index b2e29a1c9473..6734cb853b62 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -3042,6 +3042,18 @@ // //#define FF_INTERFACEBOARD +// +// MightyBoard LCD and Interface +// +//#define MIGHTYBOARD_LCD +#if ENABLED(MIGHTYBOARD_LCD) + //#define MIGHTYBOARD_DEBUG // Lightweight debug output for buttons and encoder + //#define MIGHTYBOARD_DISABLE_ENC_PULLUP // Enable if the encoder button is unreliable + //#define MIGHTYBOARD_BUTTON_PULLUPS // Enable if other buttons are unreliable + //#define MIGHTYBOARD_BACK_STATUS_BUTTONS // Use LEFT/RIGHT buttons for Back / Home. + // Otherwise they act like encoder down / up. +#endif + // // TFT GLCD Panel with Marlin UI // Panel connected to main board by SPI or I2C interface. diff --git a/Marlin/src/HAL/AVR/pinsDebug.h b/Marlin/src/HAL/AVR/pinsDebug.h index c833964a2941..ce801333a23c 100644 --- a/Marlin/src/HAL/AVR/pinsDebug.h +++ b/Marlin/src/HAL/AVR/pinsDebug.h @@ -45,7 +45,7 @@ #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14) +#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14, MIGHTYBOARD_REVG) #define AVR_ATmega2560_FAMILY_PLUS_70 1 #endif diff --git a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h index 6565acd523dc..46fe45c1f822 100644 --- a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h +++ b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h @@ -25,7 +25,7 @@ * Structures for 2560 family boards that use more than 70 pins */ -#if MB(BQ_ZUM_MEGA_3D, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14) +#if MB(BQ_ZUM_MEGA_3D, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14, MIGHTYBOARD_REVG) #undef NUM_DIGITAL_PINS #define NUM_DIGITAL_PINS 85 #elif MB(MIGHTYBOARD_REVE) diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 13d28a4a022c..718bc8f7d53d 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -187,6 +187,7 @@ #define BOARD_MALYAN_M180 1333 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only) #define BOARD_PROTONEER_CNC_SHIELD_V3 1334 // Mega controller & Protoneer CNC Shield V3.00 #define BOARD_WEEDO_62A 1335 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.) +#define BOARD_MIGHTYBOARD_REVG 1336 // Makerbot Mightyboard Revision G and H // // ATmega1281, ATmega2561 diff --git a/Marlin/src/feature/leds/pca9632.cpp b/Marlin/src/feature/leds/pca9632.cpp index d8fba380a493..29c00fc682c0 100644 --- a/Marlin/src/feature/leds/pca9632.cpp +++ b/Marlin/src/feature/leds/pca9632.cpp @@ -81,7 +81,11 @@ #define LED_ON 0x01 #define LED_PWM 0x02 -#define PCA9632_ADDRESS 0b01100000 +#ifndef PCA9632_ADDRESS + #define PCA9632_ADDRESS 0b01100000 + #warning "Using default PCA9632_ADDRESS for I2C (0b01100000)." +#endif +//static_assert(false, "Using PCA9632 I2C address=" STRINGIFY(PCA9632_ADDRESS)); byte PCA_init = 0; @@ -98,16 +102,16 @@ static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const #if DISABLED(PCA9632_NO_AUTO_INC) uint8_t data[4]; data[0] = PCA9632_AUTO_IND | regadd; - data[1 + (PCA9632_RED >> 1)] = vr; + data[1 + (PCA9632_RED >> 1)] = TERN(PCA9632_SWAP_RB, vb, vr); data[1 + (PCA9632_GRN >> 1)] = vg; - data[1 + (PCA9632_BLU >> 1)] = vb; + data[1 + (PCA9632_BLU >> 1)] = TERN(PCA9632_SWAP_RB, vr, vb); Wire.beginTransmission(I2C_ADDRESS(addr)); Wire.write(data, sizeof(data)); Wire.endTransmission(); #else - PCA9632_WriteRegister(addr, regadd + (PCA9632_RED >> 1), vr); + PCA9632_WriteRegister(addr, regadd + (PCA9632_RED >> 1), TERN(PCA9632_SWAP_RB, vb, vr)); PCA9632_WriteRegister(addr, regadd + (PCA9632_GRN >> 1), vg); - PCA9632_WriteRegister(addr, regadd + (PCA9632_BLU >> 1), vb); + PCA9632_WriteRegister(addr, regadd + (PCA9632_BLU >> 1), TERN(PCA9632_SWAP_RB, vb, vr)); #if ENABLED(PCA9632_RGBW) PCA9632_WriteRegister(addr, regadd + (PCA9632_WHT >> 1), vw); #endif @@ -132,15 +136,20 @@ void PCA9632_set_led_color(const LED1Color_t &color) { PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE); } - const byte LEDOUT = (color.r ? LED_PWM << PCA9632_RED : 0) + const byte LEDOUT = (TERN(PCA9632_SWAP_RB, color.b, color.r) ? LED_PWM << PCA9632_RED : 0) | (color.g ? LED_PWM << PCA9632_GRN : 0) - | (color.b ? LED_PWM << PCA9632_BLU : 0) + | (TERN(PCA9632_SWAP_RB, color.r, color.b) ? LED_PWM << PCA9632_BLU : 0) | (TERN0(PCA9632_RGBW, color.w ? LED_PWM << PCA9632_WHT : 0)); - PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, color.r, color.g, color.b + PCA9632_WriteAllRegisters( + PCA9632_ADDRESS, PCA9632_PWM0, + TERN(PCA9632_SWAP_RB, color.b, color.r), + color.g, + TERN(PCA9632_SWAP_RB, color.r, color.b) OPTARG(PCA9632_RGBW, color.w) ); PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_LEDOUT, LEDOUT); + } #if ENABLED(PCA9632_BUZZER) diff --git a/Marlin/src/inc/Conditionals-2-LCD.h b/Marlin/src/inc/Conditionals-2-LCD.h index 72bad45c893a..ed9b9bc370c4 100644 --- a/Marlin/src/inc/Conditionals-2-LCD.h +++ b/Marlin/src/inc/Conditionals-2-LCD.h @@ -307,6 +307,12 @@ #define IS_RRD_SC 1 #define U8GLIB_SSD1309 +#elif ENABLED(MIGHTYBOARD_LCD) + + #define IS_ULTIPANEL 1 + #define LCD_WIDTH 20 + #define LCD_HEIGHT 4 + #endif // ST7920-based graphical displays @@ -922,6 +928,7 @@ + ENABLED(CARTESIO_UI) \ + ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \ + ENABLED(FF_INTERFACEBOARD) \ + + ENABLED(MIGHTYBOARD_LCD) \ + ENABLED(FYSETC_242_OLED_12864) \ + ENABLED(G3D_PANEL) \ + ENABLED(LCD_FOR_MELZI) \ diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp index 60cb91dc79c8..fc8c741146eb 100644 --- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp @@ -89,6 +89,11 @@ #endif ); +#elif ENABLED(MIGHTYBOARD_LCD) + + // 3-wire shift-register LCD for Mightyboard + LCD_CLASS lcd; + #elif ENABLED(SR_LCD_3W_NL) // NewLiquidCrystal was not working diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.h b/Marlin/src/lcd/HD44780/marlinui_HD44780.h index 15f268f8d996..d443b048b492 100644 --- a/Marlin/src/lcd/HD44780/marlinui_HD44780.h +++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.h @@ -89,6 +89,15 @@ #include #define LCD_CLASS LiquidCrystal_SR +#elif ENABLED(MIGHTYBOARD_LCD) + + // 3-wire shift-register LCD for Mightyboard + // Optimized in-tree implementation + // Pin mapping: SR_STROBE_PIN, SR_DATA_PIN, SR_CLK_PIN + + #include "mighty/mighty_lcd_serial.h" + #define LCD_CLASS MightyboardLCDSerial + #elif ENABLED(SR_LCD_3W_NL) // NewLiquidCrystal didn't work, so this uses diff --git a/Marlin/src/lcd/HD44780/mighty/mighty_lcd_serial.cpp b/Marlin/src/lcd/HD44780/mighty/mighty_lcd_serial.cpp new file mode 100644 index 000000000000..b06652941f8c --- /dev/null +++ b/Marlin/src/lcd/HD44780/mighty/mighty_lcd_serial.cpp @@ -0,0 +1,327 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2026 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 . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if ENABLED(MIGHTYBOARD_LCD) + +#include "mighty_lcd_serial.h" +#include "../../../core/serial.h" +#include + +#include "../../../inc/MarlinConfig.h" + +/** + * Constructor: store pin assignments + */ +MightyboardLCDSerial::MightyboardLCDSerial() + : _displayfunction(LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS), + _displaycontrol(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF), + _displaymode(LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT), + _xcursor(0), _ycursor(0) {} + +/** + * Initialize LCD display with 4-bit mode + * Follows HD44780 initialization sequence from datasheet + */ +void MightyboardLCDSerial::begin(uint8_t cols, uint8_t rows, uint8_t charsize) { + SET_OUTPUT(SR_STROBE_PIN); + SET_OUTPUT(SR_DATA_PIN); + SET_OUTPUT(SR_CLK_PIN); + + // Power on LCD if power pin is defined + // Already handled in MarlinUI::init_lcd() + //#if PIN_EXISTS(LCD_PWR) + // OUT_WRITE(LCD_PWR_PIN, LOW); // Power on (active low) + //#endif + + _cols = cols; + _rows = rows; + + // Diagnostic output showing LCD configuration + #if ENABLED(MIGHTYBOARD_DEBUG) + SERIAL_ECHOLNPGM("MightyboardLCDSerial::begin() - LCD Configuration:"); + SERIAL_ECHOLNPGM(" Dimensions: ", _cols, " x ", _rows); + #ifdef LCD_WIDTH + SERIAL_ECHOLNPGM(" Expected from config: ", LCD_WIDTH, " x ", LCD_HEIGHT); + #endif + SERIAL_ECHOLN(F(" Charsize: "), + charsize == LCD_5x8DOTS ? F("5x8 dots") : charsize == LCD_5x10DOTS ? F("5x10 dots") : F("unknown") + ); + #endif + + if (rows > 1) + _displayfunction |= LCD_2LINE; + else if (rows == 1 && charsize != LCD_5x8DOTS) + _displayfunction |= LCD_5x10DOTS; + + // Power-up delay as per HD44780 datasheet (> 40ms required) + delay(50); + + // Initialization sequence for 4-bit mode + // This is a simplified sequence that works reliably + sendCommand(0x33); // Initialize, 8-bit mode attempt 1 + sendCommand(0x32); // Set 4-bit mode + sendCommand(0x28); // Function Set: 4-bit, 2-line, 5x8 dots + sendCommand(0x0C); // Display ON, cursor OFF, blink OFF + sendCommand(0x06); // Entry Mode Set: increment, no shift + sendCommand(0x01); // Clear display + delay(5); +} + +/** + * Clear the display and return cursor to home + */ +void MightyboardLCDSerial::clear() { + sendCommand(LCD_CLEARDISPLAY); + delay(2); // Clear takes ~1.52ms +} + +/** + * Return cursor to home (0, 0) + */ +void MightyboardLCDSerial::home() { + sendCommand(LCD_RETURNHOME); + delay(2); + _xcursor = 0; + _ycursor = 0; +} + +/** + * Turn display off (keeps data in DDRAM) + */ +void MightyboardLCDSerial::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + sendCommand(LCD_DISPLAYCONTROL | _displaycontrol); +} + +/** + * Turn display on + */ +void MightyboardLCDSerial::display() { + _displaycontrol |= LCD_DISPLAYON; + sendCommand(LCD_DISPLAYCONTROL | _displaycontrol); +} + +/** + * Turn off the blinking cursor + */ +void MightyboardLCDSerial::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + sendCommand(LCD_DISPLAYCONTROL | _displaycontrol); +} + +/** + * Turn on the blinking cursor + */ +void MightyboardLCDSerial::blink() { + _displaycontrol |= LCD_BLINKON; + sendCommand(LCD_DISPLAYCONTROL | _displaycontrol); +} + +/** + * Turn off the underline cursor + */ +void MightyboardLCDSerial::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + sendCommand(LCD_DISPLAYCONTROL | _displaycontrol); +} + +/** + * Turn on the underline cursor + */ +void MightyboardLCDSerial::cursor() { + _displaycontrol |= LCD_CURSORON; + sendCommand(LCD_DISPLAYCONTROL | _displaycontrol); +} + +/** + * Scroll display contents left (cursor follows) + */ +void MightyboardLCDSerial::scrollDisplayLeft() { + sendCommand(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} + +/** + * Scroll display contents right (cursor follows) + */ +void MightyboardLCDSerial::scrollDisplayRight() { + sendCommand(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +/** + * Set text direction left-to-right + */ +void MightyboardLCDSerial::leftToRight() { + _displaymode |= LCD_ENTRYLEFT; + sendCommand(LCD_ENTRYMODESET | _displaymode); +} + +/** + * Set text direction right-to-left + */ +void MightyboardLCDSerial::rightToLeft() { + _displaymode &= ~LCD_ENTRYLEFT; + sendCommand(LCD_ENTRYMODESET | _displaymode); +} + +/** + * Enable autoscroll (characters printed shift display left) + */ +void MightyboardLCDSerial::autoscroll() { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + sendCommand(LCD_ENTRYMODESET | _displaymode); +} + +/** + * Disable autoscroll + */ +void MightyboardLCDSerial::noAutoscroll() { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + sendCommand(LCD_ENTRYMODESET | _displaymode); +} + +/** + * Load a custom character into CGRAM + * @param location CGRAM address (0-7) + * @param charmap 8-byte array defining the character + */ +void MightyboardLCDSerial::createChar(uint8_t location, uint8_t charmap[]) { + location &= 0x7; // Only 8 locations available + sendCommand(LCD_SETCGRAMADDR | (location << 3)); + for (int8_t i = 0; i < 8; i++) sendData(charmap[i]); +} + +/** + * Set cursor position + * @param col Column (0 to cols-1) + * @param row Row (0 to rows-1) + */ +void MightyboardLCDSerial::setCursor(uint8_t col, uint8_t row) { + static const uint8_t row_offsets[] = {0x00, 0x40, 0x14, 0x54}; + if (row >= _rows) row = _rows - 1; + _xcursor = col; + _ycursor = row; + sendCommand(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +/** + * Write a character to the LCD at current cursor position + * Automatically advances cursor and wraps to next line if needed + */ +size_t MightyboardLCDSerial::write(uint8_t value) { + sendData(value); + _xcursor++; + if (_xcursor >= _cols) { + _xcursor = 0; + _ycursor++; + if (_ycursor >= _rows) _ycursor = 0; + setCursor(_xcursor, _ycursor); + } + return 1; +} + +/** + * Send a raw command byte to LCD + */ +void MightyboardLCDSerial::command(uint8_t value) { + send(value, false); +} + +/** + * Low-level: send 8-bit value as two 4-bit nibbles + * @param value Byte to send + * @param mode false = command, true = data + */ +void MightyboardLCDSerial::send(uint8_t value, bool mode) { + write4bits(value >> 4, mode); + write4bits(value & 0x0F, mode); +} + +/** + * Send command (RS = 0) + */ +inline void MightyboardLCDSerial::sendCommand(uint8_t value) { + send(value, false); +} + +/** + * Send data (RS = 1) + */ +inline void MightyboardLCDSerial::sendData(uint8_t value) { + send(value, true); +} + +/** + * Write 4-bit nibble to display + * @param value Lower 4 bits are used + * @param dataMode false = command (RS=0), true = data (RS=1) + */ +void MightyboardLCDSerial::write4bits(uint8_t value, bool dataMode) { + // Shift data to upper 4 bits (D7-D4 in HD44780) + uint8_t bits = value << 4; + + // Set RS bit (bit 1) based on mode + // On Mightyboard: RS = 0b0010 + if (dataMode) bits |= 0b0010; // RS = 1 for data + + // Pulse enable to latch the nibble + pulseEnable(bits); +} + +/** + * Pulse the Enable line to latch data + * On Mightyboard hardware: Enable = bit 3 (0b01000) + * @param value Pre-set data bits (D7-D0 in shift register) + */ +void MightyboardLCDSerial::pulseEnable(uint8_t value) { + _delay_us(1); + SBI(value, 3); // Set enable HIGH + writeSerial(value); + _delay_us(1); + CBI(value, 3); // Set enable LOW + writeSerial(value); + _delay_us(50); // Wait for command execution +} + +/** + * Shift out 8 bits serially via shift register + * Sends MSB first (bit 7 down to bit 0) + * @param value Byte to shift out + */ +void MightyboardLCDSerial::writeSerial(uint8_t value) { + // Shift out each bit, MSB first + for (int8_t i = 7; i >= 0; i--) { + WRITE(SR_CLK_PIN, LOW); + bool data = (value >> i) & 0x01; + WRITE(SR_DATA_PIN, data); + WRITE(SR_CLK_PIN, HIGH); + _delay_us(1); // Clock pulse width + } + + // Pulse strobe to latch data into display shift register + WRITE(SR_STROBE_PIN, HIGH); + _delay_us(1); + WRITE(SR_STROBE_PIN, LOW); +} + +#endif // MIGHTYBOARD_LCD diff --git a/Marlin/src/lcd/HD44780/mighty/mighty_lcd_serial.h b/Marlin/src/lcd/HD44780/mighty/mighty_lcd_serial.h new file mode 100644 index 000000000000..40b1b22ba77a --- /dev/null +++ b/Marlin/src/lcd/HD44780/mighty/mighty_lcd_serial.h @@ -0,0 +1,139 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2026 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 . + * + */ +#pragma once + +/** + * MightyboardLCDSerial + * Optimized 3-wire shift-register LCD driver for Mightyboard OEM displays + * Provides HD44780 compatible interface with minimal CPU overhead + */ + +#include +#include +#include + +class MightyboardLCDSerial : public Print { +public: + /** + * Constructor: initialize pin assignments + * @param strobe Strobe/latch pin (LATCH_PIN / SR_STROBE_PIN) + * @param data Data pin (MOSI_PIN / SR_DATA_PIN) + * @param clk Clock pin (SCLK_PIN / SR_CLK_PIN) + * @param pwrPin Power control pin (LCD_PWR_PIN) + */ + MightyboardLCDSerial(); + + /** + * Initialize display with given dimensions + * @param cols Number of columns (typically 20) + * @param rows Number of rows (typically 4) + */ + void begin(uint8_t cols, uint8_t rows, uint8_t charsize=LCD_5x8DOTS); + + // Basic display control + void clear(); + void home(); + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + + // Cursor movement + void setCursor(uint8_t col, uint8_t row); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void leftToRight(); + void rightToLeft(); + void autoscroll(); + void noAutoscroll(); + + // Custom characters + void createChar(uint8_t location, uint8_t charmap[]); + + // Text output + virtual size_t write(uint8_t value); + using Print::write; + + // Low-level command + void command(uint8_t value); + +private: + uint8_t _cols; + uint8_t _rows; + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + + uint8_t _xcursor; + uint8_t _ycursor; + + // Low-level communication + void send(uint8_t value, bool mode); + void sendCommand(uint8_t value); + void sendData(uint8_t value); + void write4bits(uint8_t value, bool dataMode); + void pulseEnable(uint8_t value); + void writeSerial(uint8_t value); + + // HD44780 command constants + static const uint8_t LCD_CLEARDISPLAY = 0x01; + static const uint8_t LCD_RETURNHOME = 0x02; + static const uint8_t LCD_ENTRYMODESET = 0x04; + static const uint8_t LCD_DISPLAYCONTROL = 0x08; + static const uint8_t LCD_CURSORSHIFT = 0x10; + static const uint8_t LCD_FUNCTIONSET = 0x20; + static const uint8_t LCD_SETCGRAMADDR = 0x40; + static const uint8_t LCD_SETDDRAMADDR = 0x80; + + // Entry mode flags + static const uint8_t LCD_ENTRYRIGHT = 0x00; + static const uint8_t LCD_ENTRYLEFT = 0x02; + static const uint8_t LCD_ENTRYSHIFTINCREMENT = 0x01; + static const uint8_t LCD_ENTRYSHIFTDECREMENT = 0x00; + + // Display control flags + static const uint8_t LCD_DISPLAYON = 0x04; + static const uint8_t LCD_DISPLAYOFF = 0x00; + static const uint8_t LCD_CURSORON = 0x02; + static const uint8_t LCD_CURSOROFF = 0x00; + static const uint8_t LCD_BLINKON = 0x01; + static const uint8_t LCD_BLINKOFF = 0x00; + + // Display shift flags + static const uint8_t LCD_DISPLAYMOVE = 0x08; + static const uint8_t LCD_CURSORMOVE = 0x00; + static const uint8_t LCD_MOVERIGHT = 0x04; + static const uint8_t LCD_MOVELEFT = 0x00; + + // Function set flags + static const uint8_t LCD_8BITMODE = 0x10; + static const uint8_t LCD_4BITMODE = 0x00; + static const uint8_t LCD_2LINE = 0x08; + static const uint8_t LCD_1LINE = 0x00; + static const uint8_t LCD_5x10DOTS = 0x04; + static const uint8_t LCD_5x8DOTS = 0x00; +}; + +// Alias for compatibility with Marlin's LCD_CLASS macro +using MightyboardLCD = MightyboardLCDSerial; diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index 3c30304ed8d2..9aef5cff6040 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -305,6 +305,10 @@ void MarlinUI::init_lcd() { did_init_u8g = true; } + #if PIN_EXISTS(LCD_PWR) + OUT_WRITE(LCD_PWR_PIN, LOW); + #endif + #if PIN_EXISTS(LCD_BACKLIGHT) OUT_WRITE(LCD_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT)); // Illuminate after reset or right away #endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h index 08f8ca0d8fdc..546ed792f704 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h @@ -111,13 +111,13 @@ template struct arduino_digital_pin { static constexpr uint8_t pin = p; - static void set_high() {digitalWrite(p, HIGH);} - static void set_low() {digitalWrite(p, LOW);} - static void set_input() {pinMode(p, INPUT);} - static void set_input_pullup() {pinMode(p, INPUT_PULLUP);} - static void set_output() {pinMode(p, OUTPUT);} - static uint8_t read() {return digitalRead(p);} - static void write(bool v) {digitalWrite(p, v ? HIGH : LOW);} + static void set_high() { digitalWrite(p, HIGH); } + static void set_low() { digitalWrite(p, LOW); } + static void set_input() { pinMode(p, INPUT); } + static void set_input_pullup() { pinMode(p, INPUT_PULLUP); } + static void set_output() { pinMode(p, OUTPUT); } + static uint8_t read() { return digitalRead(p); } + static void write(bool v) { digitalWrite(p, v ? HIGH : LOW); } }; #define MAKE_ARDUINO_PINS(ID) typedef arduino_digital_pin ARDUINO_DIGITAL_##ID; diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index f475b52efc31..a14fe735d42d 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -69,6 +69,11 @@ MarlinUI ui; bool MarlinUI::wait_for_move; // = false #endif +#if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS) + // Flags set from interrupt context; handled in main loop + volatile uint8_t MarlinUI::request_back = 0; +#endif + constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; #if HAS_STATUS_MESSAGE @@ -276,7 +281,7 @@ void MarlinUI::init() { SET_INPUT_PULLUP(BTN_EN2); #endif #if BUTTON_EXISTS(ENC) - SET_INPUT_PULLUP(BTN_ENC); + TERN(MIGHTYBOARD_DISABLE_ENC_PULLUP, SET_INPUT, SET_INPUT_PULLUP)(BTN_ENC); #endif #if BUTTON_EXISTS(ENC_EN) SET_INPUT_PULLUP(BTN_ENC_EN); @@ -285,16 +290,16 @@ void MarlinUI::init() { SET_INPUT_PULLUP(BTN_BACK); #endif #if BUTTON_EXISTS(UP) - SET_INPUT(BTN_UP); + TERN(MIGHTYBOARD_BUTTON_PULLUPS, SET_INPUT_PULLUP, SET_INPUT)(BTN_UP); #endif #if BUTTON_EXISTS(DOWN) - SET_INPUT(BTN_DOWN); + TERN(MIGHTYBOARD_BUTTON_PULLUPS, SET_INPUT_PULLUP, SET_INPUT)(BTN_DOWN); #endif #if BUTTON_EXISTS(LFT) - SET_INPUT(BTN_LEFT); + TERN(MIGHTYBOARD_BUTTON_PULLUPS, SET_INPUT_PULLUP, SET_INPUT)(BTN_LEFT); #endif #if BUTTON_EXISTS(RT) - SET_INPUT(BTN_RIGHT); + TERN(MIGHTYBOARD_BUTTON_PULLUPS, SET_INPUT_PULLUP, SET_INPUT)(BTN_RIGHT); #endif #if HAS_SHIFT_ENCODER @@ -1032,6 +1037,16 @@ void MarlinUI::init() { wait_for_unclick = false; } + #if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS) + // Handle requests set from interrupt context (ISR-safe) + if (request_back) { + quick_feedback(); + if (request_back == 1) goto_previous_screen(); + else if (request_back == 2) return_to_status(); + request_back = 0; + } + #endif + if (LCD_BACK_CLICKED()) { quick_feedback(); goto_previous_screen(); @@ -1395,11 +1410,19 @@ void MarlinUI::init() { next_button_update_ms = now + 300; } else if (BUTTON_PRESSED(LEFT)) { - encoderDiff = -pulses; + #if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS) + request_back = 1; // ISR-safe: flag action run in the main loop + #else + encoderDiff = -pulses; + #endif next_button_update_ms = now + 300; } else if (BUTTON_PRESSED(RIGHT)) { - encoderDiff = pulses; + #if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS) + request_back = 2; // ISR-safe: flag action run in the main loop + #else + encoderDiff = -pulses; + #endif next_button_update_ms = now + 300; } diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 15f355ccd054..e581070a7518 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -836,6 +836,11 @@ class MarlinUI { static void update_buttons(); + #if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS) + // Requests set from interrupt context and handled in main loop + static volatile uint8_t request_back; + #endif + #if ENABLED(ENCODER_NOISE_FILTER) /** * Some printers may have issues with EMI noise especially using a motherboard with 3.3V logic levels diff --git a/Marlin/src/libs/softspi.h b/Marlin/src/libs/softspi.h index f9408904e11c..162e1770334f 100644 --- a/Marlin/src/libs/softspi.h +++ b/Marlin/src/libs/softspi.h @@ -207,7 +207,16 @@ {&DDRJ, &PINJ, &PORTJ, 5}, // J5 76 {&DDRJ, &PINJ, &PORTJ, 6}, // J6 77 {&DDRE, &PINE, &PORTE, 2}, // E2 78 - {&DDRE, &PINE, &PORTE, 6} // E6 79 + {&DDRE, &PINE, &PORTE, 6}, // E6 79 + + // pins_MIGHTYBOARD_REVG.h + // TODO: Only include with a -D define in build + {&DDRE, &PINE, &PORTE, 7}, // E7 80 + {&DDRD, &PIND, &PORTD, 4}, // D4 81 + {&DDRD, &PIND, &PORTD, 5}, // D5 82 + {&DDRD, &PIND, &PORTD, 6}, // D6 83 + {&DDRH, &PINH, &PORTH, 2}, // H2 84 + {&DDRH, &PINH, &PORTH, 7} // H7 85 }; #elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__) \ diff --git a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h index 9dc0c5f7d859..5d023941f679 100644 --- a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h +++ b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h @@ -24,7 +24,7 @@ /** * Mightyboard Rev.E pin assignments * Schematic: https://github.com/sciguy14/HelioWatcher/blob/master/HelioWatcher%20Circuit/MakerBot%20MightyBoard%20REVE%20Schematic.pdf - * also works for Rev D boards. It's all rev E despite what the silk screen says + * also works for Rev D boards. It's all rev E despite what the silkscreen says. */ /** @@ -183,6 +183,43 @@ #define CUTOFF_TEST_PIN 17 // H0 #define CUTOFF_SR_CHECK_PIN 70 // G4 (TOSC1) +#if HAS_TMC_UART + /** + * TMC220x stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + #define X_HARDWARE_SERIAL Serial2 + #define Y_HARDWARE_SERIAL Serial1 + + /** + * Software serial + */ + + #define X_SERIAL_TX_PIN 16 + #define X_SERIAL_RX_PIN 17 + + #define Y_SERIAL_TX_PIN 18 + #define Y_SERIAL_RX_PIN 19 + + #define Z_SERIAL_TX_PIN 41 + #define Z_SERIAL_RX_PIN 66 + + #define E0_SERIAL_TX_PIN 40 + #define E0_SERIAL_RX_PIN 67 + + #define E1_SERIAL_TX_PIN 37 + #define E1_SERIAL_RX_PIN 68 + +#endif // HAS_TMC_UART + +// +// SD Card +// +#define SD_SS_PIN 53 // B0 +#define SD_DETECT_PIN 9 // H6 + // // LCD / Controller // @@ -220,10 +257,6 @@ #define BTN_LEFT 72 // J2 #define BTN_RIGHT 14 // J1 - // Disable encoder - #undef BTN_EN1 - #undef BTN_EN2 - #define BEEPER_PIN 4 // G5 #define STAT_LED_RED_PIN 32 // C5 @@ -235,40 +268,3 @@ #define BTN_ENC BTN_CENTER #endif // HAS_WIRED_LCD - -// -// SD Card -// -#define SD_SS_PIN 53 // B0 -#define SD_DETECT_PIN 9 // H6 - -#if HAS_TMC_UART - /** - * TMC220x stepper drivers - * - * Hardware serial communication ports. - * If undefined software serial is used according to the pins below - */ - #define X_HARDWARE_SERIAL Serial2 - #define Y_HARDWARE_SERIAL Serial1 - - /** - * Software serial - */ - - #define X_SERIAL_TX_PIN 16 - #define X_SERIAL_RX_PIN 17 - - #define Y_SERIAL_TX_PIN 18 - #define Y_SERIAL_RX_PIN 19 - - #define Z_SERIAL_TX_PIN 41 - #define Z_SERIAL_RX_PIN 66 - - #define E0_SERIAL_TX_PIN 40 - #define E0_SERIAL_RX_PIN 67 - - #define E1_SERIAL_TX_PIN 37 - #define E1_SERIAL_RX_PIN 68 - -#endif diff --git a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVG.h b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVG.h new file mode 100644 index 000000000000..61c6340a026d --- /dev/null +++ b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVG.h @@ -0,0 +1,202 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2026 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 . + * + */ +#pragma once + +/** + * Mightyboard Rev.G and H pin assignments + * Schematic: not avalable (as rev G and H are not open source) + * Pins based on the work of https://github.com/Sgail7/Replicator-Revival-Project/ + * Pin number according to Mega extended mega2560ext: .\buildroot\share\PlatformIO\variants\MARLIN_MEGA_EXTENDED\pins_arduino.h + * Corrected pins based on Marlin\src\libs\softspi.h + * Use env:MightyBoard2560 or env:MightyBoard1280 in platformio.ini + */ + +#define ALLOW_MEGA1280 +#include "env_validate.h" + +#define BOARD_INFO_NAME "Mightyboard rev.G/H" +#define DEFAULT_MACHINE_NAME "MB Replicator" + +// +// Limit Switches: X and Y go to max, Z to min +// +#define X_STOP_PIN 30 // C7 +#define Y_STOP_PIN 31 // C6 +#define Z_STOP_PIN 32 // C5 + +// +// Steppers +// +#define X_STEP_PIN 83 // D6 +#define X_DIR_PIN 38 // D7 +#define X_ENABLE_PIN 81 // D4 + +#define Y_STEP_PIN 44 // L5 +#define Y_DIR_PIN 42 // L7 +#define Y_ENABLE_PIN 45 // L4 + +#define Z_STEP_PIN 48 // L1 +#define Z_DIR_PIN 47 // L2 +#define Z_ENABLE_PIN 49 // L0 + +#define E0_STEP_PIN 25 // A3 +#define E0_DIR_PIN 24 // A2 +#define E0_ENABLE_PIN 27 // A5 + +#define E1_STEP_PIN 22 // A0 +#define E1_DIR_PIN 15 // K7 +#define E1_ENABLE_PIN 23 // A1 + +/** + * I2C Digipots - MCP4018 + * Address 5E (2F << 1) + * Set from 0 - 127 with stop bit. + * (Ex. 3F << 1 | 1) + */ +#define DIGIPOTS_I2C_SCL 28 // A6 +#define DIGIPOTS_I2C_SDA_X 82 // D5 +#define DIGIPOTS_I2C_SDA_Y 43 // L6 +#define DIGIPOTS_I2C_SDA_Z 46 // L3 +#define DIGIPOTS_I2C_SDA_E0 26 // A4 +#define DIGIPOTS_I2C_SDA_E1 74 // J7 + +#ifndef DIGIPOT_I2C_ADDRESS_A + #define DIGIPOT_I2C_ADDRESS_A 0x2F // unshifted slave address (5E <- 2F << 1) +#endif +#define DIGIPOT_ENABLE_I2C_PULLUPS // MightyBoard doesn't have hardware I2C pin pull-ups. + +// Bed temp sensor pin +#define TEMP_BED_PIN 3 // F3 + +/** + * Temperature Sensors + * Uses ADS1118 as ADC converter to read the hotend temperature sensors + * SPI for ADS1118 ADC, Uses software SPI + */ +#define TEMP_0_CS_PIN 79 // E6 +#define TEMP_0_SCK_PIN 78 // E2 +#define TEMP_0_MISO_PIN 80 // E7 +#define TEMP_0_MOSI_PIN 84 // H2 + +#define TEMP_1_CS_PIN 2 // E4 +#define TEMP_1_SCK_PIN TEMP_0_SCK_PIN +#define TEMP_1_MISO_PIN TEMP_0_MISO_PIN +#define TEMP_1_MOSI_PIN TEMP_0_MOSI_PIN + +// +// FET Pin Mapping - FET A is closest to the input power connector +// + +#define MOSFET_A_PIN 3 // E5 +#define MOSFET_B_PIN 5 // E3 +#define MOSFET_C_PIN 8 // H5 +#define MOSFET_D_PIN 7 // H4 +#define MOSFET_E_PIN 2 // E4 +#define MOSFET_F_PIN 4 // G5 + +// +// Heaters / Fans (24V) +// + +#define HEATER_0_PIN MOSFET_A_PIN // E5 +#define HEATER_1_PIN MOSFET_B_PIN // E3 ?* +#define HEATER_BED_PIN MOSFET_C_PIN // H5 + +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN MOSFET_D_PIN +#elif !defined(FAN0_PIN) + #define FAN0_PIN MOSFET_D_PIN +#endif + +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN MOSFET_E_PIN +#elif !defined(FAN1_PIN) + #define FAN1_PIN MOSFET_E_PIN +#endif + +// +// LCD / Controller +// + +#if IS_RRD_FG_SC + + #define BEEPER_PIN 8 // H5, SD_WP + + #define BTN_EN2 75 // J4, UP + #define BTN_EN1 73 // J3, DOWN + + #define LCD_PINS_RS 33 // C4: LCD-STROBE + #define LCD_PINS_EN 72 // J2: LEFT + #define LCD_PINS_D4 35 // C2: LCD-CLK + #define LCD_PINS_D5 32 // C5: RLED + #define LCD_PINS_D6 34 // C3: LCD-DATA + #define LCD_PINS_D7 31 // C6: GLED + + // STOP button connected as KILL_PIN + #define KILL_PIN 14 // J1, RIGHT (not connected) + + // Onboard leds + #define STAT_LED_RED_PIN SERVO0_PIN // C1 (1280-EX1, DEBUG2) + #define STAT_LED_BLUE_PIN SERVO1_PIN // C0 (1280-EX2, DEBUG3) + +#elif HAS_WIRED_LCD + + // Replicator 2 and 2X uses a HD44780 SPI display, pins: mosi, sclk, miso (not used), missing: latch, click, power + + #define BEEPER_PIN 6 // H3 + + // Map the CLICK button to the encoder 'click' so Marlin treats it as SELECT + #ifndef BTN_ENC + #define BTN_ENC BTN_CENTER + #endif + + #define BTN_CENTER 39 // G2 + #define BTN_UP 76 // J5 + #define BTN_DOWN 75 // J4 + #define BTN_LEFT 77 // J6 + #define BTN_RIGHT 73 // J3 + + #define SR_DATA_PIN 37 // C0 + #define SR_CLK_PIN 36 // C1 + #define SR_STROBE_PIN 34 // C3 + #define SR_DETECT_PIN 33 // C4 + + #define LCD_PWR_PIN 29 // A7 + + #define BUTTON_LED_PIN 35 // C2 To be implemented... + + /** + * SD Card + * + * NOTE: With SD support enabled it is implicitly assumed + * that the following pins are connected: + * AVR | SD header + *---------|-------------- + * MISO | DATA_OUT + * MOSI | DATA_IN + * SCK | CLK + */ + //#define SD_WRITE_PIN 41 // Sailfish mighty two: G0(41) H5(D8) - + #define SD_DETECT_PIN 40 // Sailfish mighty two: G1(40) H6(D9) L0(D49) + #define SD_SS_PIN 53 // Sailfish mighty two: B0(53) + +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 6c4894f20dab..c2933eb5fb15 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -317,6 +317,8 @@ #include "mega/pins_PROTONEER_CNC_SHIELD_V3.h" // ATmega2560 env:mega2560 #elif MB(WEEDO_62A) #include "mega/pins_WEEDO_62A.h" // ATmega2560 env:mega2560 +#elif MB(MIGHTYBOARD_REVG) + #include "mega/pins_MIGHTYBOARD_REVG.h" // ATmega2560, ATmega1280 env:MightyBoard2560 env:MightyBoard1280 env:mega2560ext // // ATmega1281, ATmega2561 diff --git a/Marlin/src/pins/pinsDebug_list.h b/Marlin/src/pins/pinsDebug_list.h index a6807f5c69cb..bb8d282a5392 100644 --- a/Marlin/src/pins/pinsDebug_list.h +++ b/Marlin/src/pins/pinsDebug_list.h @@ -960,6 +960,9 @@ #if PIN_EXISTS(LCD_BACKLIGHT) REPORT_NAME_DIGITAL(__LINE__, LCD_BACKLIGHT_PIN) #endif +#if PIN_EXISTS(LCD_PWR) + REPORT_NAME_DIGITAL(__LINE__, LCD_PWR_PIN) +#endif #if PIN_EXISTS(DOGLCD_SCL) REPORT_NAME_DIGITAL(__LINE__, DOGLCD_SCL_PIN) #endif diff --git a/ini/features.ini b/ini/features.ini index 03a9bdbba8d1..cb006f3f6fd6 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -40,9 +40,10 @@ USES_LIQUIDCRYSTAL = LiquidCrystal=https://github.com/Marlin USES_LIQUIDCRYSTAL_I2C = marcoschwartz/LiquidCrystal_I2C@1.1.4 USES_LIQUIDTWI2 = LiquidTWI2@1.2.7 HAS_LCDPRINT = build_src_filter=+ -HAS_MARLINUI_HD44780 = build_src_filter=+ HAS_MARLINUI_U8GLIB = marlinfirmware/U8glib-HAL@0.5.5 build_src_filter=+ +HAS_MARLINUI_HD44780 = build_src_filter=+ - +MIGHTYBOARD_LCD = build_src_filter=+ HAS_(FSMC|SPI|LTDC)_TFT = build_src_filter=+ I2C_EEPROM = build_src_filter=+ SOFT_I2C_EEPROM|U8G_USES_SW_I2C = SlowSoftI2CMaster, SlowSoftWire=https://github.com/felias-fogg/SlowSoftWire/archive/f34d777f39.zip