This commit is contained in:
Axel Sepúlveda 2026-02-26 18:24:44 -08:00 committed by GitHub
commit c1ea28c1a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 863 additions and 18 deletions

View file

@ -3042,6 +3042,20 @@
//
//#define FF_INTERFACEBOARD
//
// MightyBoard LCD and Interface
//
//#define MIGHTYBOARD_LCD
#if ENABLED(MIGHTYBOARD_LCD)
//#define MIGHTYBOARD_RUNTIME_DEBUG // Lightweight debug output for buttons and encoder
//#define MIGHTYBOARD_DISABLE_ENC_PULLUP // Enable if the encoder button doesn't work correctly
//#define MIGHTYBOARD_BUTTON_PULLUPS // Enable if other buttons don't work correctly
// Enable to use LEFT/RIGHT for Back and Status Screen.
// Otherwise LEFT/RIGHT act like the encoder in menu navigation and value editing.
//#define MIGHTYBOARD_BACK_STATUS_BUTTONS
#endif // MIGHTYBOARD_LCD
//
// TFT GLCD Panel with Marlin UI
// Panel connected to main board by SPI or I2C interface.

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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) \

View file

@ -0,0 +1,331 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*
*/
#include "MightyboardLCDSerial.h"
#include "../../inc/MarlinConfigPre.h"
#include "../../core/serial.h"
#if HAS_MARLINUI_HD44780 && ENABLED(MIGHTYBOARD_LCD)
#include <util/delay.h>
/**
* Constructor: store pin assignments
*/
MightyboardLCDSerial::MightyboardLCDSerial(uint8_t strobe, uint8_t data, uint8_t clk, uint8_t pwrPin)
: _strobe_pin(strobe), _data_pin(data), _clk_pin(clk), _pwr_pin(pwrPin),
_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) {
pinMode(_strobe_pin, OUTPUT);
pinMode(_data_pin, OUTPUT);
pinMode(_clk_pin, OUTPUT);
// Power on LCD if power pin is defined
if (_pwr_pin != 255) {
pinMode(_pwr_pin, OUTPUT);
digitalWrite(_pwr_pin, LOW); // Power on (active low)
}
_cols = cols;
_rows = rows;
// Diagnostic output showing LCD configuration
#if ENABLED(MIGHTYBOARD_RUNTIME_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_ECHOPGM(" Charsize: ");
if (charsize == LCD_5x8DOTS)
SERIAL_ECHOLNPGM("5x8 dots");
else if (charsize == LCD_5x10DOTS)
SERIAL_ECHOLNPGM("5x10 dots");
else
SERIAL_ECHOLNPGM("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);
value |= 0b00001000; // Set enable HIGH
writeSerial(value);
_delay_us(1);
value &= 0b11110111; // 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--) {
digitalWrite(_clk_pin, LOW);
bool data = (value >> i) & 0x01;
digitalWrite(_data_pin, data);
digitalWrite(_clk_pin, HIGH);
_delay_us(1); // Clock pulse width
}
// Pulse strobe to latch data into display shift register
digitalWrite(_strobe_pin, HIGH);
_delay_us(1);
digitalWrite(_strobe_pin, LOW);
}
#endif // HAS_MARLINUI_HD44780 && ENABLED(MIGHTYBOARD_LCD)

View file

@ -0,0 +1,142 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* MightyboardLCDSerial
* Optimized 3-wire shift-register LCD driver for Mightyboard OEM displays
* Provides HD44780 compatible interface with minimal CPU overhead
*/
#include <Arduino.h>
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(uint8_t strobe, uint8_t data, uint8_t clk, uint8_t pwrPin = 255);
/**
* 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 _strobe_pin;
uint8_t _data_pin;
uint8_t _clk_pin;
uint8_t _pwr_pin;
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;

View file

@ -89,6 +89,16 @@
#endif
);
#elif ENABLED(MIGHTYBOARD_LCD)
// 3-wire shift-register LCD for Mightyboard
// Optimized in-tree implementation
#if PIN_EXISTS(LCD_PWR)
LCD_CLASS lcd(SR_STROBE_PIN, SR_DATA_PIN, SR_CLK_PIN, LCD_PWR_PIN);
#else
LCD_CLASS lcd(SR_STROBE_PIN, SR_DATA_PIN, SR_CLK_PIN);
#endif
#elif ENABLED(SR_LCD_3W_NL)
// NewLiquidCrystal was not working

View file

@ -89,6 +89,15 @@
#include <LiquidCrystal_SR.h>
#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 "MightyboardLCDSerial.h"
#define LCD_CLASS MightyboardLCDSerial
#elif ENABLED(SR_LCD_3W_NL)
// NewLiquidCrystal didn't work, so this uses

View file

@ -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

View file

@ -69,6 +69,12 @@ 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 bool MarlinUI::request_back = false,
MarlinUI::request_return_to_status = false;
#endif
constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
#if HAS_STATUS_MESSAGE
@ -276,7 +282,11 @@ void MarlinUI::init() {
SET_INPUT_PULLUP(BTN_EN2);
#endif
#if BUTTON_EXISTS(ENC)
SET_INPUT_PULLUP(BTN_ENC);
#if ENABLED(MIGHTYBOARD_DISABLE_ENC_PULLUP)
SET_INPUT(BTN_ENC);
#else
SET_INPUT_PULLUP(BTN_ENC);
#endif
#endif
#if BUTTON_EXISTS(ENC_EN)
SET_INPUT_PULLUP(BTN_ENC_EN);
@ -285,18 +295,68 @@ void MarlinUI::init() {
SET_INPUT_PULLUP(BTN_BACK);
#endif
#if BUTTON_EXISTS(UP)
SET_INPUT(BTN_UP);
#if ENABLED(MIGHTYBOARD_BUTTON_PULLUPS)
SET_INPUT_PULLUP(BTN_UP);
#else
SET_INPUT(BTN_UP);
#endif
#endif
#if BUTTON_EXISTS(DOWN)
SET_INPUT(BTN_DOWN);
#if ENABLED(MIGHTYBOARD_BUTTON_PULLUPS)
SET_INPUT_PULLUP(BTN_DOWN);
#else
SET_INPUT(BTN_DOWN);
#endif
#endif
#if BUTTON_EXISTS(LFT)
SET_INPUT(BTN_LEFT);
#if ENABLED(MIGHTYBOARD_BUTTON_PULLUPS)
SET_INPUT_PULLUP(BTN_LEFT);
#else
SET_INPUT(BTN_LEFT);
#endif
#endif
#if BUTTON_EXISTS(RT)
SET_INPUT(BTN_RIGHT);
#if ENABLED(MIGHTYBOARD_BUTTON_PULLUPS)
SET_INPUT_PULLUP(BTN_RIGHT);
#else
SET_INPUT(BTN_RIGHT);
#endif
#endif
// Compile-time warnings to confirm whether this directional-button init block
// is compiled for the current board. These will appear in the compiler output
// only when ANY_BUTTON(UP, DOWN, LFT, RT) evaluates true for the current build.
//#if ENABLED(MIGHTYBOARD_RUNTIME_DEBUG) && ANY_BUTTON(UP, DOWN, LFT, RT)
// #warning "Marlin: Compiling directional button init (UP/DOWN/LEFT/RIGHT)"
//#endif
// Optional runtime trace for MightyBoard UI/button flow.
// Enable by uncommenting `#define MIGHTYBOARD_RUNTIME_DEBUG` in the board pins file.
//#if ENABLED(MIGHTYBOARD_RUNTIME_DEBUG)
// SERIAL_ECHOLN("MarlinUI::init() - MIGHTYBOARD_RUNTIME_DEBUG active");
// #if ENABLED(MIGHTYBOARD_BUTTON_PULLUPS)
// SERIAL_ECHOLN("MIGHTYBOARD_BUTTON_PULLUPS: ENABLED");
// #else
// SERIAL_ECHOLN("MIGHTYBOARD_BUTTON_PULLUPS: DISABLED");
// #endif
// SERIAL_ECHO_MSG("LCD dimensions: ", LCD_WIDTH, " x ", LCD_HEIGHT);
// SERIAL_ECHOLN("");
//
//// Report encoder/click compile-time presence and pin numbers (if defined)
// #if BUTTON_EXISTS(ENC)
// SERIAL_ECHOLN("BUTTON_EXISTS(ENC): defined");
// SERIAL_ECHO_MSG("BTN_ENC pin: ", BTN_ENC);
// SERIAL_ECHOLN("");
// #else
// SERIAL_ECHOLN("BUTTON_EXISTS(ENC): NOT defined");
// #endif
//
// #ifdef BTN_CLICK
// SERIAL_ECHO_MSG("BTN_CLICK pin: ", BTN_CLICK);
// SERIAL_ECHOLN("");
// #endif
//#endif // MIGHTYBOARD_RUNTIME_DEBUG
#if HAS_SHIFT_ENCODER
#if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register
@ -1031,6 +1091,19 @@ void MarlinUI::init() {
else
wait_for_unclick = false;
}
#if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS)
// Handle requests set from interrupt context (ISR-safe)
if (request_back) {
request_back = false;
quick_feedback();
goto_previous_screen();
}
if (request_return_to_status) {
request_return_to_status = false;
quick_feedback();
return_to_status();
}
#endif
if (LCD_BACK_CLICKED()) {
quick_feedback();
@ -1357,6 +1430,18 @@ void MarlinUI::init() {
void MarlinUI::update_buttons() {
const millis_t now = millis();
//#if ENABLED(MIGHTYBOARD_RUNTIME_DEBUG)
// // Debug: print raw pin reads for encoder/click to diagnose BTN_ENC alias
// #if BUTTON_EXISTS(ENC)
// SERIAL_ECHO_MSG("DBG: READ(BTN_ENC) = ", READ(BTN_ENC));
// SERIAL_ECHOLN("");
// #endif
// #ifdef BTN_CLICK
// SERIAL_ECHO_MSG("DBG: READ(BTN_CLICK) = ", READ(BTN_CLICK));
// SERIAL_ECHOLN("");
// #endif
//#endif
#if HAS_MARLINUI_ENCODER
const int8_t delta = get_encoder_delta(now);
@ -1389,17 +1474,29 @@ void MarlinUI::init() {
if (BUTTON_PRESSED(UP)) {
encoderDiff = pulses * (ENCODER_STEPS_PER_MENU_ITEM);
next_button_update_ms = now + 300;
//#if ENABLED(MIGHTYBOARD_RUNTIME_DEBUG)
// SERIAL_ECHO_MSG("update_buttons(): UP -> encoderDiff=", encoderDiff);
// SERIAL_ECHOLN("");
//#endif
}
else if (BUTTON_PRESSED(DOWN)) {
encoderDiff = pulses * -(ENCODER_STEPS_PER_MENU_ITEM);
next_button_update_ms = now + 300;
}
else if (BUTTON_PRESSED(LEFT)) {
encoderDiff = -pulses;
#if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS)
request_back = true; // 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_return_to_status = true; // ISR-safe: flag action run in the main loop
#else
encoderDiff = -pulses;
#endif
next_button_update_ms = now + 300;
}

View file

@ -836,6 +836,11 @@ public:
static void update_buttons();
#if ENABLED(MIGHTYBOARD_BACK_STATUS_BUTTONS)
// Requests set from interrupt context and handled in main loop
static volatile bool request_back, request_return_to_status;
#endif
#if ENABLED(ENCODER_NOISE_FILTER)
/**
* Some printers may have issues with EMI noise especially using a motherboard with 3.3V logic levels

View file

@ -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__) \

View file

@ -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 <https://www.gnu.org/licenses/>.
*
*/
#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

View file

@ -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

View file

@ -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