diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 0a22283ff075..7faffd1a08c1 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -77,7 +77,7 @@ * Serial port -1 is the USB emulated serial port, if available. * Note: The first serial port (-1 or 0) will always be used by the Arduino bootloader. * - * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] */ #define SERIAL_PORT -1 @@ -99,7 +99,7 @@ /** * Select a secondary serial port on the board to use for communication with the host. * Currently Ethernet (-2) is only supported on Teensy 4.1 boards. - * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] + * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] */ //#define SERIAL_PORT_2 -1 //#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE @@ -107,11 +107,21 @@ /** * Select a third serial port on the board to use for communication with the host. * Currently only supported for AVR, DUE, LPC1768/9 and STM32/STM32F1 - * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] */ //#define SERIAL_PORT_3 1 //#define BAUDRATE_3 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE +/** + * Select a serial port to communicate with RS485 protocol + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +//#define RS485_SERIAL_PORT 1 +#ifdef RS485_SERIAL_PORT + //#define M485_PROTOCOL 1 // Check your host for protocol compatibility + //#define RS485_BUS_BUFFER_SIZE 128 +#endif + // Enable the Bluetooth serial interface on AT90USB devices //#define BLUETOOTH diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index d95c8ca828cd..17d26ee81bfc 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -603,7 +603,9 @@ * (Does not work on Sanguinololu with FAN_SOFT_PWM.) */ #define FAN_KICKSTART_TIME 200 // (ms) -#define FAN_KICKSTART_POWER 200 // 64-255 +#define FAN_KICKSTART_POWER 255 // 64-255 +#define FAN_KICKSTART_LINEAR // Set kickstart time linearly based on the speed, e.g., for 20% (51) it will be FAN_KICKSTART_TIME * 0.2. + // Useful for quick speed up to low speed. Kickstart power must be set to 255. // Some coolers may require a non-zero "off" state. //#define FAN_OFF_PWM 1 diff --git a/Marlin/Version.h b/Marlin/Version.h index 9922ba35a5db..c76fd3814a5a 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-07-02" +//#define STRING_DISTRIBUTION_DATE "2024-07-12" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/HAL/ESP32/timers.h b/Marlin/src/HAL/ESP32/timers.h index aa4e1551f066..3f336fbfc962 100644 --- a/Marlin/src/HAL/ESP32/timers.h +++ b/Marlin/src/HAL/ESP32/timers.h @@ -53,12 +53,11 @@ typedef uint64_t hal_timer_t; #if ENABLED(I2S_STEPPER_STREAM) #define STEPPER_TIMER_PRESCALE 1 #define STEPPER_TIMER_RATE 250000 // 250khz, 4µs pulses of i2s word clock - #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs // wrong would be 0.25 #else #define STEPPER_TIMER_PRESCALE 40 #define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz - #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs #endif +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs #define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index 9c74a95ff0c4..e25ca27d8eda 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -117,6 +117,14 @@ #endif #endif +#ifdef RS485_SERIAL_PORT + #if WITHIN(RS485_SERIAL_PORT, 1, 9) + #define RS485_SERIAL MSERIAL(RS485_SERIAL_PORT) + #else + #error "RS485_SERIAL_PORT must be from 1 to 9." + #endif +#endif + /** * TODO: review this to return 1 for pins that are not analog input */ diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp index c4bc62994908..862678373fb1 100644 --- a/Marlin/src/HAL/STM32/MarlinSerial.cpp +++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp @@ -37,6 +37,9 @@ #ifndef USART5 #define USART5 UART5 #endif +#ifndef USART6 + #define USART6 UART6 +#endif #ifndef USART7 #define USART7 UART7 #endif diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h index 007bf83b0974..c422f60500b6 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -143,6 +143,17 @@ #endif #endif +#ifdef RS485_SERIAL_PORT + #if RS485_SERIAL_PORT == -1 + #define RS485_SERIAL UsbSerial + #elif WITHIN(RS485_SERIAL_PORT, 1, NUM_UARTS) + #define RS485_SERIAL MSERIAL(RS485_SERIAL_PORT) + #else + #define RS485_SERIAL MSERIAL(1) // dummy port + static_assert(false, "RS485_SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ".") + #endif +#endif + /** * TODO: review this to return 1 for pins that are not analog input */ diff --git a/Marlin/src/HAL/TEENSY31_32/timers.h b/Marlin/src/HAL/TEENSY31_32/timers.h index 9fcbb6f232c9..3bbc2421e006 100644 --- a/Marlin/src/HAL/TEENSY31_32/timers.h +++ b/Marlin/src/HAL/TEENSY31_32/timers.h @@ -41,7 +41,7 @@ typedef uint32_t hal_timer_t; #define FTM0_TIMER_PRESCALE_BITS 0b011 #define FTM1_TIMER_PRESCALE_BITS 0b010 -#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500kHz +#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7.5MHz #define FTM1_TIMER_RATE (F_BUS / (FTM1_TIMER_PRESCALE)) // 60MHz / 4 = 15MHz #define HAL_TIMER_RATE (FTM0_TIMER_RATE) diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index be81388f3896..c9a0a5432ec7 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -261,9 +261,13 @@ #include "tests/marlin_tests.h" #endif +#if HAS_RS485_SERIAL + #include "feature/rs485.h" +#endif + PGMSTR(M112_KILL_STR, "M112 Shutdown"); -MarlinState marlin_state = MF_INITIALIZING; +MarlinState marlin_state = MarlinState::MF_INITIALIZING; // For M109 and M190, this flag may be cleared (by M108) to exit the wait loop bool wait_for_heatup = false; @@ -377,8 +381,8 @@ void startOrResumeJob() { } inline void finishSDPrinting() { - if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued - marlin_state = MF_RUNNING; // Signal to stop trying + if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued + marlin_state = MarlinState::MF_RUNNING; // Signal to stop trying TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine()); TERN_(DGUS_LCD_UI_MKS, screen.sdPrintingFinished()); } @@ -773,7 +777,7 @@ void idle(const bool no_stepper_sleep/*=false*/) { TERN_(MAX7219_DEBUG, max7219.idle_tasks()); // Return if setup() isn't completed - if (marlin_state == MF_INITIALIZING) goto IDLE_DONE; + if (marlin_state == MarlinState::MF_INITIALIZING) goto IDLE_DONE; // TODO: Still causing errors TERN_(TOOL_SENSOR, (void)check_tool_sensor_stats(active_extruder, true)); @@ -959,7 +963,7 @@ void stop() { SERIAL_ERROR_MSG(STR_ERR_STOPPED); LCD_MESSAGE(MSG_STOPPED); safe_delay(350); // allow enough time for messages to get out before stopping - marlin_state = MF_STOPPED; + marlin_state = MarlinState::MF_STOPPED; } } @@ -1273,7 +1277,7 @@ void setup() { // Identify myself as Marlin x.x.x SERIAL_ECHOLNPGM("Marlin " SHORT_BUILD_VERSION); - #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR) + #ifdef STRING_DISTRIBUTION_DATE SERIAL_ECHO_MSG( " Last Updated: " STRING_DISTRIBUTION_DATE " | Author: " STRING_CONFIG_H_AUTHOR @@ -1642,11 +1646,15 @@ void setup() { SETUP_RUN(bdl.init(I2C_BD_SDA_PIN, I2C_BD_SCL_PIN, I2C_BD_DELAY)); #endif + #if HAS_RS485_SERIAL + SETUP_RUN(rs485_init()); + #endif + #if ENABLED(FT_MOTION) SETUP_RUN(ftMotion.init()); #endif - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; #ifdef STARTUP_TUNE // Play a short startup tune before continuing. @@ -1678,7 +1686,7 @@ void loop() { #if HAS_MEDIA if (card.flag.abort_sd_printing) abortSDPrinting(); - if (marlin_state == MF_SD_COMPLETE) finishSDPrinting(); + if (marlin_state == MarlinState::MF_SD_COMPLETE) finishSDPrinting(); #endif queue.advance(); diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h index e9c63bb31f35..9cf74de2c68f 100644 --- a/Marlin/src/MarlinCore.h +++ b/Marlin/src/MarlinCore.h @@ -42,7 +42,7 @@ void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, co void minkill(const bool steppers_off=false); // Global State of the firmware -enum MarlinState : uint8_t { +enum class MarlinState : uint8_t { MF_INITIALIZING = 0, MF_STOPPED, MF_KILLED, @@ -53,8 +53,8 @@ enum MarlinState : uint8_t { }; extern MarlinState marlin_state; -inline bool IsRunning() { return marlin_state >= MF_RUNNING; } -inline bool IsStopped() { return marlin_state == MF_STOPPED; } +inline bool IsRunning() { return marlin_state >= MarlinState::MF_RUNNING; } +inline bool IsStopped() { return marlin_state == MarlinState::MF_STOPPED; } bool printingIsActive(); bool printJobOngoing(); diff --git a/Marlin/src/feature/backlash.cpp b/Marlin/src/feature/backlash.cpp index 07fa7725a06c..3b9d78cb2e89 100644 --- a/Marlin/src/feature/backlash.cpp +++ b/Marlin/src/feature/backlash.cpp @@ -171,13 +171,14 @@ int32_t Backlash::get_applied_steps(const AxisEnum axis) { const int32_t residual_error_axis = residual_error[axis]; - // At startup it is assumed the last move was forward. - // So the applied steps will always be negative. + // At startup, when no steps are applied, it is assumed the last move was backwards. + // So the applied steps will always be zero (when moving backwards) or a positive + // number (when moving forwards). - if (forward) return -residual_error_axis; + if (!forward) return -residual_error_axis; const float f_corr = float(correction) / all_on; - const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; + const int32_t full_error_axis = f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; return full_error_axis - residual_error_axis; } diff --git a/Marlin/src/feature/ethernet.cpp b/Marlin/src/feature/ethernet.cpp index c5bfa932cb5b..9b022b4e17e3 100644 --- a/Marlin/src/feature/ethernet.cpp +++ b/Marlin/src/feature/ethernet.cpp @@ -141,7 +141,7 @@ void MarlinEthernet::check() { case CONNECTING: telnetClient.println("Marlin " SHORT_BUILD_VERSION); - #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR) + #ifdef STRING_DISTRIBUTION_DATE telnetClient.println( " Last Updated: " STRING_DISTRIBUTION_DATE " | Author: " STRING_CONFIG_H_AUTHOR diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp index ac7f1815162b..8810c518cf70 100644 --- a/Marlin/src/feature/leds/leds.cpp +++ b/Marlin/src/feature/leds/leds.cpp @@ -239,7 +239,7 @@ void LEDLights::set_color(const LEDColor &incol void LEDLights::toggle() { if (lights_on) set_off(); else update(); } #endif -#if LED_POWEROFF_TIMEOUT > 0 +#if HAS_LED_POWEROFF_TIMEOUT millis_t LEDLights::led_off_time; // = 0 diff --git a/Marlin/src/feature/leds/leds.h b/Marlin/src/feature/leds/leds.h index 7a31ca685d49..da8ba42fba1a 100644 --- a/Marlin/src/feature/leds/leds.h +++ b/Marlin/src/feature/leds/leds.h @@ -164,11 +164,11 @@ class LEDLights { #if ENABLED(LED_CONTROL_MENU) static void toggle(); // swap "off" with color #endif - #if ANY(LED_CONTROL_MENU, CASE_LIGHT_USE_RGB_LED) || LED_POWEROFF_TIMEOUT > 0 + #if ANY(LED_CONTROL_MENU, CASE_LIGHT_USE_RGB_LED, HAS_LED_POWEROFF_TIMEOUT) static void update() { set_color(color); } #endif - #if LED_POWEROFF_TIMEOUT > 0 + #if HAS_LED_POWEROFF_TIMEOUT private: static millis_t led_off_time; public: diff --git a/Marlin/src/feature/power.cpp b/Marlin/src/feature/power.cpp index 20eb63a6f160..c6dc56283692 100644 --- a/Marlin/src/feature/power.cpp +++ b/Marlin/src/feature/power.cpp @@ -201,7 +201,7 @@ void Power::power_off() { /** * Check all conditions that would signal power needing to be on. * - * @returns bool if power is needed + * @return bool if power is needed */ bool Power::is_power_needed() { diff --git a/Marlin/src/feature/rs485.cpp b/Marlin/src/feature/rs485.cpp new file mode 100644 index 000000000000..800918545081 --- /dev/null +++ b/Marlin/src/feature/rs485.cpp @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 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/MarlinConfig.h" + +#if HAS_RS485_SERIAL + +#include "rs485.h" + +HardwareSerialBusIO rs485BusIO(&RS485_SERIAL); +RS485Bus rs485Bus(rs485BusIO, RS485_RX_ENABLE_PIN, RS485_TX_ENABLE_PIN); + +PhotonProtocol rs485Protocol; + +Packetizer rs485Packetizer(rs485Bus, rs485Protocol); + +uint8_t rs485Buffer[RS485_SEND_BUFFER_SIZE]; + +void rs485_init() { RS485_SERIAL.begin(57600); } + +#endif // HAS_RS485_SERIAL diff --git a/Marlin/src/feature/rs485.h b/Marlin/src/feature/rs485.h new file mode 100644 index 000000000000..3327626a3c05 --- /dev/null +++ b/Marlin/src/feature/rs485.h @@ -0,0 +1,40 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 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 + +#include "../inc/MarlinConfigPre.h" + +#include +#include + +#include +#include + +#define RS485_SEND_BUFFER_SIZE 32 + +extern HardwareSerialBusIO rs485BusIO; +extern RS485Bus rs485Bus; +extern PhotonProtocol rs485Protocol; +extern Packetizer rs485Packetizer; +extern uint8_t rs485Buffer[RS485_SEND_BUFFER_SIZE]; + +void rs485_init(); diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp index 59e0db132a71..12aed8631663 100644 --- a/Marlin/src/gcode/calibrate/G33.cpp +++ b/Marlin/src/gcode/calibrate/G33.cpp @@ -634,7 +634,7 @@ void GcodeSuite::G33() { } SERIAL_EOL(); - MString<20> msg(F("Calibration sd:")); + MString<21> msg(F("Calibration sd:")); if (zero_std_dev_min < 1) msg.appendf(F("0.%03i"), (int)LROUND(zero_std_dev_min * 1000.0f)); else diff --git a/Marlin/src/gcode/control/M999.cpp b/Marlin/src/gcode/control/M999.cpp index b7d6db9f2312..b4278fccad27 100644 --- a/Marlin/src/gcode/control/M999.cpp +++ b/Marlin/src/gcode/control/M999.cpp @@ -36,7 +36,7 @@ * existing command buffer. */ void GcodeSuite::M999() { - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; ui.reset_alert_level(); if (parser.boolval('S')) return; diff --git a/Marlin/src/gcode/feature/rs485/M485.cpp b/Marlin/src/gcode/feature/rs485/M485.cpp new file mode 100644 index 000000000000..03640a034eec --- /dev/null +++ b/Marlin/src/gcode/feature/rs485/M485.cpp @@ -0,0 +1,127 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 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/MarlinConfig.h" + +#if HAS_RS485_SERIAL + +#include "../../../feature/rs485.h" +#include "../../gcode.h" + +void write_packet_data() { + + Packet packet = rs485Packetizer.getPacket(); + for (size_t i = packet.startIndex; i <= packet.endIndex; i++) { + const uint8_t data = rs485Bus[i]; + if (data < 0x10) SERIAL_ECHOPGM_P(PSTR("0")); + SERIAL_PRINT(data, PrintBase::Hex); + } + + SERIAL_EOL(); +} + +static void rs485_write_failed(const PacketWriteResult writeResult) { + SERIAL_ERROR_START(); + SERIAL_ECHOPGM("RS485: Write failed "); + switch (writeResult) { + case PacketWriteResult::FAILED_INTERRUPTED: SERIAL_ECHOPGM("interrupted"); break; + case PacketWriteResult::FAILED_BUFFER_FULL: SERIAL_ECHOPGM("buffer full"); break; + case PacketWriteResult::FAILED_TIMEOUT: SERIAL_ECHOPGM("timeout"); break; + } + SERIAL_EOL(); +} + +void GcodeSuite::M485() { + if (strlen(parser.string_arg) & 1) { + SERIAL_ERROR_MSG("String must contain an even number of bytes."); + return; + } + + if (strlen(parser.string_arg) > RS485_SEND_BUFFER_SIZE * 2) { + SERIAL_ERROR_MSG("String too long (" STRINGIFY(RS485_SEND_BUFFER_SIZE) " bytes max)."); + return; + } + + // Convert the string to bytes in the buffer + for (size_t i = 0; i < strlen(parser.string_arg); i += 2) { + const uint8_t nybble1 = HEXCHR(parser.string_arg[i]), + nybble2 = HEXCHR(parser.string_arg[i + 1]); + + if (nybble1 == -1 || nybble2 == -1) { + SERIAL_ERROR_START(); + SERIAL_ECHOPGM("Not a hex character: "); + SERIAL_CHAR(nybble1 == -1 ? parser.string_arg[i] : parser.string_arg[i+1]); + SERIAL_EOL(); + return; + } + + rs485Buffer[i >> 1] = (nybble1 & 0x0F) << 4 | (nybble2 & 0x0F); + } + + rs485Packetizer.setMaxReadTimeout(50000); // This can be super small since ideally any packets will already be in our buffer + rs485Packetizer.setFalsePacketVerificationTimeout(5000); + + // Read and ignore any packets that may have come in, before we write. + + while (rs485Packetizer.hasPacket()) { + #if M485_PROTOCOL >= 2 + SERIAL_ECHO_START(); + #endif + SERIAL_ECHO(F("rs485-"), F("unexpected-packet: ")); + write_packet_data(); + rs485Packetizer.clearPacket(); + } + + const PacketWriteResult writeResult = rs485Packetizer.writePacket(rs485Buffer, strlen(parser.string_arg) / 2); + switch (writeResult) { + default: rs485_write_failed(writeResult); + case PacketWriteResult::OK: break; // Nothing to do + } + + //millis_t startTime = millis(); + bool hasPacket = rs485Packetizer.hasPacket(); + //millis_t endTime = millis(); + //#if M485_PROTOCOL >= 2 + // SERIAL_ECHO_START(); + //#endif + //SERIAL_ECHOLN(F("rs485-"), F("time: "), endTime - startTime); + + #if M485_PROTOCOL >= 2 + SERIAL_ECHO_START(); + #endif + + SERIAL_ECHO(F("rs485-")); + if (!hasPacket) { + #if M485_PROTOCOL >= 2 + SERIAL_ECHOLN(F("timeout")); + #else + SERIAL_ECHOLN(F("reply: TIMEOUT")); + #endif + return; + } + + SERIAL_ECHO(F("reply: ")); + write_packet_data(); + rs485Packetizer.clearPacket(); +} + +#endif // HAS_RS485_SERIAL diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 9e81c7d4bc4b..2a8bfa4e662a 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -897,6 +897,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 430: M430(); break; // M430: Read the system current (A), voltage (V), and power (W) #endif + #if HAS_RS485_SERIAL + case 485: M485(); break; // M485: Send RS485 packets + #endif + #if ENABLED(CANCEL_OBJECTS) case 486: M486(); break; // M486: Identify and cancel objects #endif diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 144d724cd9cd..bb2f0099949b 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -243,6 +243,7 @@ * M425 - Enable/Disable and tune backlash correction. (Requires BACKLASH_COMPENSATION and BACKLASH_GCODE) * M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA) * M430 - Read the system current, voltage, and power (Requires POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE, or POWER_MONITOR_FIXED_VOLTAGE) + * M485 - Send RS485 packets (Requires RS485_SERIAL_PORT) * M486 - Identify and cancel objects. (Requires CANCEL_OBJECTS) * M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS) * M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS) @@ -1063,6 +1064,10 @@ class GcodeSuite { static void M430(); #endif + #if HAS_RS485_SERIAL + static void M485(); + #endif + #if ENABLED(CANCEL_OBJECTS) static void M486(); #endif diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index 16c3b2d9bd0b..4b8bbb925fde 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -274,9 +274,12 @@ void GCodeParser::parse(char *p) { // Only use string_arg for these M codes if (letter == 'M') switch (codenum) { - TERN_(GCODE_MACROS, case 810 ... 819:) TERN_(EXPECTED_PRINTER_CHECK, case 16:) - case 23: case 28: case 30: case 117 ... 118: case 928: + TERN_(SDSUPPORT, case 23: case 28: case 30: case 928:) + TERN_(HAS_STATUS_MESSAGE, case 117:) + TERN_(HAS_RS485_SERIAL, case 485:) + TERN_(GCODE_MACROS, case 810 ... 819:) + case 118: string_arg = unescape_string(p); return; default: break; diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 7de6146f293c..573cfb0d3c75 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -26,6 +26,10 @@ * Conditionals that need to be set before Configuration_adv.h or pins.h */ +#ifndef STRING_CONFIG_H_AUTHOR + #define STRING_CONFIG_H_AUTHOR "(anonymous)" +#endif + /** * Extruders have some combination of stepper motors and hotends * so we separate these concepts into the defines: @@ -654,11 +658,11 @@ #elif ENABLED(ZONESTAR_12864OLED) #define IS_RRD_SC 1 - #define U8GLIB_SH1106 + #define U8GLIB_SH1106_SPI #elif ENABLED(ZONESTAR_12864OLED_SSD1306) #define IS_RRD_SC 1 - #define IS_U8GLIB_SSD1306 + #define U8GLIB_SSD1306_SPI #elif ENABLED(RADDS_DISPLAY) #define IS_ULTIPANEL 1 @@ -716,7 +720,7 @@ #elif ENABLED(SAV_3DGLCD) - #ifdef U8GLIB_SSD1306 + #if ENABLED(U8GLIB_SSD1306) #define IS_U8GLIB_SSD1306 // Allow for U8GLIB_SSD1306 + SAV_3DGLCD #endif #define IS_NEWPANEL 1 @@ -857,9 +861,12 @@ #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 #endif -// 128x64 I2C OLED LCDs - SSD1306/SSD1309/SH1106 +// 128x64 I2C OLED LCDs (SSD1306 / SSD1309 / SH1106) +// ...and 128x64 SPI OLED LCDs (SSD1306 / SH1106) #if ANY(U8GLIB_SSD1306, U8GLIB_SSD1309, U8GLIB_SH1106) #define HAS_U8GLIB_I2C_OLED 1 +#endif +#if ANY(HAS_U8GLIB_I2C_OLED, U8GLIB_SSD1306_SPI, U8GLIB_SH1106_SPI) #define HAS_WIRED_LCD 1 #define DOGLCD #endif @@ -1666,6 +1673,9 @@ #if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1 || SERIAL_PORT_3 == -1 #define HAS_USB_SERIAL 1 #endif +#ifdef RS485_SERIAL_PORT + #define HAS_RS485_SERIAL 1 +#endif #if SERIAL_PORT_2 == -2 #define HAS_ETHERNET 1 #endif @@ -1895,6 +1905,10 @@ #define NEOPIXEL_BKGD_INDEX_LAST NEOPIXEL_BKGD_INDEX_FIRST #endif +#if LED_POWEROFF_TIMEOUT > 0 + #define HAS_LED_POWEROFF_TIMEOUT 1 +#endif + #if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE) #define SPI_FLASH_BACKUP 1 #endif diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index d1524cf82a12..e6f307877d0f 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -1827,11 +1827,12 @@ // // Flag the indexed hardware serial ports in use -#define SERIAL_IN_USE(N) ( (defined(SERIAL_PORT) && N == SERIAL_PORT) \ - || (defined(SERIAL_PORT_2) && N == SERIAL_PORT_2) \ - || (defined(SERIAL_PORT_3) && N == SERIAL_PORT_3) \ - || (defined(MMU2_SERIAL_PORT) && N == MMU2_SERIAL_PORT) \ - || (defined(LCD_SERIAL_PORT) && N == LCD_SERIAL_PORT) ) +#define SERIAL_IN_USE(N) ( (defined(SERIAL_PORT) && N == SERIAL_PORT) \ + || (defined(SERIAL_PORT_2) && N == SERIAL_PORT_2) \ + || (defined(SERIAL_PORT_3) && N == SERIAL_PORT_3) \ + || (defined(MMU2_SERIAL_PORT) && N == MMU2_SERIAL_PORT) \ + || (defined(LCD_SERIAL_PORT) && N == LCD_SERIAL_PORT) \ + || (defined(RS485_SERIAL_PORT) && N == RS485_SERIAL_PORT) ) // Flag the named hardware serial ports in use #define TMC_UART_IS(A,N) (defined(A##_HARDWARE_SERIAL) && (CAT(HW_,A##_HARDWARE_SERIAL) == HW_Serial##N || CAT(HW_,A##_HARDWARE_SERIAL) == HW_MSerial##N)) @@ -2757,7 +2758,7 @@ // Fan Kickstart #if FAN_KICKSTART_TIME && !defined(FAN_KICKSTART_POWER) - #define FAN_KICKSTART_POWER 180 + #define FAN_KICKSTART_POWER TERN(FAN_KICKSTART_LINEAR, 255, 180) #endif // Servos diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index f1101461d959..b13377cf5f9e 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1009,8 +1009,12 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif // Fan Kickstart power -#if FAN_KICKSTART_TIME && !WITHIN(FAN_KICKSTART_POWER, 64, 255) - #error "FAN_KICKSTART_POWER must be an integer from 64 to 255." +#if FAN_KICKSTART_TIME + #if ENABLED(FAN_KICKSTART_LINEAR) && FAN_KICKSTART_POWER != 255 + #error "FAN_KICKSTART_LINEAR requires a FAN_KICKSTART_POWER of 255." + #elif !WITHIN(FAN_KICKSTART_POWER, 64, 255) + #error "FAN_KICKSTART_POWER must be an integer from 64 to 255." + #endif #endif /** @@ -2915,6 +2919,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "MMU2_SERIAL_PORT cannot be the same as SERIAL_PORT_2." #elif defined(LCD_SERIAL_PORT) && MMU2_SERIAL_PORT == LCD_SERIAL_PORT #error "MMU2_SERIAL_PORT cannot be the same as LCD_SERIAL_PORT." + #elif defined(RS485_SERIAL_PORT) && MMU2_SERIAL_PORT == RS485_SERIAL_PORT + #error "MMU2_SERIAL_PORT cannot be the same as RS485_SERIAL_PORT." #endif #endif @@ -2926,6 +2932,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "LCD_SERIAL_PORT cannot be the same as SERIAL_PORT." #elif defined(SERIAL_PORT_2) && LCD_SERIAL_PORT == SERIAL_PORT_2 #error "LCD_SERIAL_PORT cannot be the same as SERIAL_PORT_2." + #elif defined(RS485_SERIAL_PORT) && LCD_SERIAL_PORT == RS485_SERIAL_PORT + #error "LCD_SERIAL_PORT cannot be the same as RS485_SERIAL_PORT." #endif #else #if HAS_DGUS_LCD @@ -2939,6 +2947,17 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #endif +/** + * RS485 bus requires a dedicated serial port + */ +#ifdef RS485_SERIAL_PORT + #if RS485_SERIAL_PORT == SERIAL_PORT + #error "RS485_SERIAL_PORT cannot be the same as SERIAL_PORT." + #elif defined(SERIAL_PORT_2) && RS485_SERIAL_PORT == SERIAL_PORT_2 + #error "RS485_SERIAL_PORT cannot be the same as SERIAL_PORT_2." + #endif +#endif + /** * Check existing CS pins against enabled TMC SPI drivers. */ diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index c06e9ca2aaae..38b96cb847e3 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-07-02" + #define STRING_DISTRIBUTION_DATE "2024-07-12" #endif /** diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index eed2bf22751a..5e5267c95a40 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -392,7 +392,7 @@ void MarlinUI::clear_for_drawing() { #if HAS_DISPLAY_SLEEP void MarlinUI::sleep_display(const bool sleep/*=true*/) { static bool asleep = false; - if (asleep != sleep){ + if (asleep != sleep) { sleep ? u8g.sleepOn() : u8g.sleepOff(); asleep = sleep; } diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.h b/Marlin/src/lcd/dogm/marlinui_DOGM.h index 9025395f5600..d3f38cd61994 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.h +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.h @@ -155,7 +155,11 @@ #if ENABLED(ALTERNATIVE_LCD) #define U8G_CLASS U8GLIB_SH1306_128X64_2X // 4 stripes #else - #define U8G_CLASS U8GLIB_SH1306_128X64 // 8 stripes + #if ENABLED(U8GLIB_SSD1306_SPI) + #define U8G_CLASS U8GLIB_SSD1306_128X64_SW_SPI_HAL + #else + #define U8G_CLASS U8GLIB_SH1306_128X64 // 8 stripes + #endif #endif #elif ANY(MKS_12864OLED, ZONESTAR_12864OLED) @@ -168,7 +172,11 @@ #if ENABLED(ALTERNATIVE_LCD) #define U8G_CLASS U8GLIB_SH1106_128X64_2X // 4 stripes #else - #define U8G_CLASS U8GLIB_SH1106_128X64 // 8 stripes + #if ENABLED(U8GLIB_SH1106_SPI) + #define U8G_CLASS U8GLIB_SH1106_128X64_SW_SPI_HAL + #else + #define U8G_CLASS U8GLIB_SH1106_128X64 // 8 stripes + #endif #endif #elif ENABLED(U8GLIB_SH1106_EINSTART) diff --git a/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h b/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h index 907fa43c9bd7..33a9c21c4109 100644 --- a/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h +++ b/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h @@ -23,7 +23,7 @@ #include "../../../inc/MarlinConfig.h" -// use this file to create the public interface for device drivers that are NOT in the U8G library +// Use this file to create the public interface for device drivers that are NOT in the U8G library extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_sw_spi; extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_hw_spi; @@ -90,6 +90,30 @@ class U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE : public U8GLIB { void init(uint8_t options = U8G_I2C_OPT_NONE) { U8GLIB::init(&u8g_dev_ssd1306_128x64_2x_i2c_2_wire, options); } }; +#if ENABLED(U8GLIB_SH1106_SPI) + extern u8g_dev_t u8g_dev_sh1106_128x64_HAL_sw_spi; + class U8GLIB_SH1106_128X64_SW_SPI_HAL : public U8GLIB { + public: + U8GLIB_SH1106_128X64_SW_SPI_HAL() : U8GLIB() { } + U8GLIB_SH1106_128X64_SW_SPI_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) {init(sck, mosi, cs, reset); } + void init(pin_t sck, pin_t mosi, pin_t cs, pin_t reset=U8G_PIN_NONE) { + U8GLIB::init(&u8g_dev_sh1106_128x64_HAL_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset); + } + }; +#endif + +#if ENABLED(U8GLIB_SSD1306_SPI) + extern u8g_dev_t u8g_dev_ssd1306_128x64_HAL_sw_spi; + class U8GLIB_SSD1306_128X64_SW_SPI_HAL : public U8GLIB { + public: + U8GLIB_SSD1306_128X64_SW_SPI_HAL() : U8GLIB() { } + U8GLIB_SSD1306_128X64_SW_SPI_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) {init(sck, mosi, cs, reset); } + void init(pin_t sck, pin_t mosi, pin_t cs, pin_t reset=U8G_PIN_NONE) { + U8GLIB::init(&u8g_dev_ssd1306_128x64_HAL_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset); + } + }; +#endif + // // Very basic support for 320x240 TFT screen // Tested on MKS Robin TFT_V2.0 with ST7789V controller diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp index 4cd9b8f3c06d..4d4756c298cf 100644 --- a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp @@ -77,35 +77,34 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq); -// The sh1106 is compatible to the ssd1306, but is 132x64. 128x64 display area is centered within -// the 132x64. +// SH1106 (132x64) is compatible with SSD1306 (128x64) by adding a small margin to the larger display + +#define SH1106_PAGE_ADR(N) (0x20), (N) +#define SH1106_COL_ADR(N) (0x10 | ((N) >> 4)), ((N) & 0xFF) +#define SH1106_COLUMN_RANGE(N,O) (0x21), (N), (O) +#define SH1106_PAGE_RANGE(N,O) (0x22), (N), (O) +#define SH1106_SCROLL(N) ((N) ? 0x2F : 0x2E) +#define SH1106_START_LINE(N) (0x40 | (N)) +#define SH1106_CONTRAST(N) (0x81), (N) +#define SH1106_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) +#define SH1106_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) +#define SH1106_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) +#define SH1106_INVERTED(N) ((N) ? 0xA7 : 0xA6) +#define SH1106_MUX_RATIO(N) (0xA8), (N) +#define SH1106_ON(N) ((N) ? 0xAF : 0xAE) +#define SH1106_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) +#define SH1106_DISP_OFFS(N) (0xD3), (N) +#define SH1106_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) +#define SH1106_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) +#define SH1106_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) +#define SH1106_VCOM_DESEL(N) (0xDB), (N) +#define SH1106_NOOP() (0xE3) static const uint8_t u8g_dev_sh1106_128x64_data_start_2_wire[] PROGMEM = { - 0x010, // set upper 4 bit of the col adr to 0 - 0x002, // set lower 4 bit of the col adr to 2 (centered display with ssd1306) - U8G_ESC_END // end of sequence + SH1106_COL_ADR(2), // Column 2 to center 128 pixels in 132 pixels + U8G_ESC_END // End of sequence }; -#define SH1106_PAGE_ADR(N) (0x20), (N) -#define SH1106_COLUMN_RANGE(N) (0x21), (((N) >> 8) & 0xFF), ((N) & 0xFF) -#define SH1106_PAGE_RANGE(N,O) (0x22), (N), (O) -#define SH1106_SCROLL(N) ((N) ? 0x2F : 0x2E) -#define SH1106_START_LINE(N) (0x40 | (N)) -#define SH1106_CONTRAST(N) (0x81), (N) -#define SH1106_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) -#define SH1106_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) -#define SH1106_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) -#define SH1106_INVERTED(N) ((N) ? 0xA7 : 0xA6) -#define SH1106_MUX_RATIO(N) (0xA8), (N) -#define SH1106_ON(N) ((N) ? 0xAF : 0xAE) -#define SH1106_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) -#define SH1106_DISP_OFFS(N) (0xD3), (N) -#define SH1106_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) -#define SH1106_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) -#define SH1106_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) -#define SH1106_VCOM_DESEL(N) (0xDB), (N) -#define SH1106_NOOP() (0xE3) - static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { U8G_ESC_ADR(0), // Initiate command mode SH1106_ON(0), // Display off, sleep mode @@ -113,19 +112,19 @@ static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { SH1106_DISP_OFFS(0), // Display offset SH1106_START_LINE(0), // Start line SH1106_ADC_REVERSE(1), // Segment remap A0/A1 - SH1106_OUT_MODE(1), // C0: scan dir normal, C8: reverse - SH1106_COM_CONFIG(1), // Com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) - SH1106_CONTRAST(0xCF), // [2] set contrast control - SH1106_PAGE_ADR(0x02), // 2012-05-27: page addressing mode - SH1106_COLUMN_RANGE(0x281), // Set column range from 0 through 131 - SH1106_PAGE_RANGE(0, 7), // Set page range from 0 through 7 - SH1106_CHARGE_PER(0x1, 0xF), // [2] pre-charge period 0x22/F1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0xCF), // Set contrast control + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_COLUMN_RANGE(2, 129), // Set column range 2 .. 129 + SH1106_PAGE_RANGE(0, 7), // Set page range 0 .. 7 + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period SH1106_VCOM_DESEL(0x40), // Vcomh deselect level - SH1106_ALL_PIX(0), // Output ram to display + SH1106_ALL_PIX(0), // Output RAM to display SH1106_INVERTED(0), // Normal display mode SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) - SH1106_CHARGE_PUMP(1), // [2] charge pump setting (P62): 0x14 enable, 0x10 disable - SH1106_SCROLL(0), // 2012-05-27: Deactivate scroll + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_SCROLL(0), // Deactivate scroll SH1106_ON(1), // Display on U8G_ESC_END // End of sequence }; @@ -136,28 +135,24 @@ uint8_t u8g_dev_sh1106_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t m u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_init_seq_2_wire); break; - case U8G_DEV_MSG_STOP: - break; + case U8G_DEV_MSG_STOP: break; case U8G_DEV_MSG_PAGE_NEXT: { - u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); - u8g_SetChipSelect(u8g, dev, 0); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2+1)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); - u8g_SetChipSelect(u8g, dev, 0); - } - break; - case U8G_DEV_MSG_SLEEP_ON: - return 1; - case U8G_DEV_MSG_SLEEP_OFF: - return 1; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2+1)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: return 1; + case U8G_DEV_MSG_SLEEP_OFF: return 1; } return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); } @@ -169,33 +164,32 @@ u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire = { u8g_dev_sh1106_128x64_2x_2_wir ///////////////////////////////////////////////////////////////////////////////////////////// static const uint8_t u8g_dev_ssd1306_128x64_data_start_2_wire[] PROGMEM = { - 0x010, // set upper 4 bit of the col adr to 0 - 0x000, // set lower 4 bit of the col adr to 0 - U8G_ESC_END // end of sequence + SH1106_COL_ADR(0), // Column 0 + U8G_ESC_END // End of sequence }; static const uint8_t u8g_dev_ssd1306_128x64_init_seq_2_wire[] PROGMEM = { - U8G_ESC_ADR(0), // initiate command mode - 0x0AE, // display off, sleep mode - 0x0A8, 0x03F, // mux ratio - 0x0D3, 0x00, // display offset - 0x040, // start line - 0x0A1, // segment remap a0/a1 - 0x0C8, // c0: scan dir normal, c8: reverse - 0x0DA, 0x012, // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) - 0x081, 0x0CF, // [2] set contrast control - 0x020, 0x002, // 2012-05-27: page addressing mode - 0x21, 0, 0x7F, // set column range from 0 through 127 - 0x22, 0, 7, // set page range from 0 through 7 - 0x0D9, 0x0F1, // [2] pre-charge period 0x022/f1 - 0x0DB, 0x040, // vcomh deselect level - 0x0A4, // output ram to display - 0x0A6, // none inverted normal display mode - 0x0D5, 0x080, // clock divide ratio (0x00=1) and oscillator frequency (0x8) - 0x08D, 0x014, // [2] charge pump setting (p62): 0x014 enable, 0x010 disable - 0x02E, // 2012-05-27: Deactivate scroll - 0x0AF, // display on - U8G_ESC_END // end of sequence + U8G_ESC_CS(0), // Disable chip + SH1106_ON(0), // Display off, sleep mode + SH1106_MUX_RATIO(0x3F), // Mux ratio + SH1106_DISP_OFFS(0), // Display offset + SH1106_START_LINE(0), // Start line + SH1106_ADC_REVERSE(1), // Segment remap A0/A1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0xCF), // Set contrast control + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_COLUMN_RANGE(0, 127), // Set column range 0 .. 127 + SH1106_PAGE_RANGE(0, 7), // Set page range from 0 .. 7 + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period + SH1106_VCOM_DESEL(0x40), // Vcomh deselect level + SH1106_ALL_PIX(0), // Send RAM to display + SH1106_INVERTED(0), // Normal display mode + SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_SCROLL(0), // Deactivate scroll + SH1106_ON(1), // Display on + U8G_ESC_END // End of sequence }; uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { @@ -204,28 +198,24 @@ uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_init_seq_2_wire); break; - case U8G_DEV_MSG_STOP: - break; + case U8G_DEV_MSG_STOP: break; case U8G_DEV_MSG_PAGE_NEXT: { - u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); - u8g_SetChipSelect(u8g, dev, 0); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2+1)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); - u8g_SetChipSelect(u8g, dev, 0); - } - break; - case U8G_DEV_MSG_SLEEP_ON: - return 1; - case U8G_DEV_MSG_SLEEP_OFF: - return 1; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2+1)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: return 1; + case U8G_DEV_MSG_SLEEP_OFF: return 1; } return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); } @@ -236,10 +226,10 @@ u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire = { u8g_dev_ssd1306_128x64_2x_2_w ///////////////////////////////////////////////////////////////////////////////////////////// -// This routine adds the instruction byte in between the command bytes. This makes the init -// sequences a lot easier to read. +// This routine adds the instruction byte in between the command bytes. +// This makes the init sequences a lot easier to read. -#define I2C_CMD_MODE 0x080 +#define I2C_CMD_MODE 0x80 uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq) { uint8_t is_escape = 0; @@ -247,10 +237,8 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s uint8_t value = u8g_pgm_read(esc_seq); if (is_escape == 0) { if (value != 255) { - if (u8g_WriteByte(u8g, dev, value) == 0 ) - return 0; - if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) - return 0; + if (u8g_WriteByte(u8g, dev, value) == 0) return 0; + if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0) return 0; } else { is_escape = 1; @@ -258,16 +246,14 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s } else { if (value == 255) { - if (u8g_WriteByte(u8g, dev, value) == 0 ) - return 0; - if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) - return 0; + if (u8g_WriteByte(u8g, dev, value) == 0) return 0; + if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0) return 0; } else if (value == 254) { break; } - else if (value >= 0x0F0) { - /* not yet used, do nothing */ + else if (value >= 0xF0) { + // not yet used, do nothing } else if (value >= 0xE0 ) { u8g_SetAddress(u8g, dev, value & 0x0F); @@ -279,13 +265,14 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s u8g_SetResetLow(u8g, dev); value &= 0x0F; value <<= 4; - value+=2; + value += 2; u8g_Delay(value); u8g_SetResetHigh(u8g, dev); u8g_Delay(value); } - else if (value >= 0xBE) { /* not yet implemented */ - /* u8g_SetVCC(u8g, dev, value & 0x01); */ + else if (value >= 0xBE) { + // not yet implemented + //u8g_SetVCC(u8g, dev, value & 0x01); } else if (value <= 127) { u8g_Delay(value); diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp new file mode 100644 index 000000000000..afb3c28a8ce3 --- /dev/null +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp @@ -0,0 +1,246 @@ +/** + * 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 . + * + */ + +/** + * Based on u8g_dev_ssd1306_128x64.c + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2015, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../../../inc/MarlinConfig.h" + +#if ALL(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI) && ANY(U8GLIB_SH1106_SPI, U8GLIB_SSD1306_SPI) + +#include "HAL_LCD_com_defines.h" + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + +#define SH1106_PAGE_ADR(N) (0x20), (N) +#define SH1106_COL_ADR(N) (0x10 | ((N) >> 4)), ((N) & 0xFF) +#define SH1106_COLUMN_RANGE(N,O) (0x21), (N), (O) +#define SH1106_PAGE_RANGE(N,O) (0x22), (N), (O) +#define SH1106_SCROLL(N) ((N) ? 0x2F : 0x2E) +#define SH1106_START_LINE(N) (0x40 | (N)) +#define SH1106_CONTRAST(N) (0x81), (N) +#define SH1106_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) +#define SH1106_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) +#define SH1106_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) +#define SH1106_INVERTED(N) ((N) ? 0xA7 : 0xA6) +#define SH1106_MUX_RATIO(N) (0xA8), (N) +#define SH1106_ON(N) ((N) ? 0xAF : 0xAE) +#define SH1106_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) +#define SH1106_DISP_OFFS(N) (0xD3), (N) +#define SH1106_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) +#define SH1106_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) +#define SH1106_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) +#define SH1106_VCOM_DESEL(N) (0xDB), (N) +#define SH1106_NOOP() (0xE3) + +static const uint8_t u8g_dev_ssd13xx_HAL_sleep_on[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_ON(0) // Display off + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +static const uint8_t u8g_dev_ssd13xx_HAL_sleep_off[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_ON(1), // Display on + U8G_ESC_DLY(50), // Delay 50 ms + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +#if ENABLED(U8GLIB_SH1106_SPI) + +// Init sequence Adafruit 128x64 OLED (NOT TESTED). Like Adafruit3, but with page addressing mode. +static const uint8_t u8g_dev_sh1106_128x64_HAL_init_seq[] PROGMEM = { + U8G_ESC_CS(0), // Disable chip + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds + U8G_ESC_CS(1), // Enable chip + SH1106_ON(0), // Display off, sleep mode + SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) + SH1106_MUX_RATIO(0x3F), // Mux ratio + SH1106_DISP_OFFS(0), // Display offset + SH1106_START_LINE(0), // Start line + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_ADC_REVERSE(1), // Segment remap A0/A1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0x80), // Set contrast control + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period + SH1106_VCOM_DESEL(0x40), // Vcomh deselect level + SH1106_SCROLL(0), // Deactivate scroll + SH1106_ALL_PIX(0), // Output RAM to display + SH1106_INVERTED(0), // Normal display mode + SH1106_ON(1), // Display on + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +// SH1106 (132x64) is compatible with SSD1306 (128x64) by adding a small margin to the larger display +static const uint8_t u8g_dev_sh1106_128x64_HAL_data_start[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_COL_ADR(2), // Column 2 to center 128 pixels in 132 pixels + U8G_ESC_END // End of sequence +}; + +uint8_t u8g_dev_sh1106_128x64_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { + switch(msg) { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_sh1106_128x64_HAL_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_sh1106_128x64_HAL_data_start); + u8g_WriteByte(u8g, dev, 0x0B0 | pb->p.page); // Select current page (SSD1306) + u8g_SetAddress(u8g, dev, 1); // Data mode + if (u8g_pb_WriteBuffer(pb, u8g, dev) == 0) return 0; + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_off); + return 1; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteByte(u8g, dev, 0x81); + u8g_WriteByte(u8g, dev, *(uint8_t *) arg); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_sh1106_128x64_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_sh1106_128x64_HAL_fn, U8G_COM_HAL_SW_SPI_FN); + +#elif ENABLED(U8GLIB_SSD1306_SPI) + +static const uint8_t u8g_dev_ssd1306_128x64_HAL_init_seq[] PROGMEM = { + U8G_ESC_CS(0), // Disable chip + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds + U8G_ESC_CS(1), // Enable chip + SH1106_ON(0), // Display off, sleep mode + SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) + SH1106_MUX_RATIO(0x3F), // Mux ratio + SH1106_DISP_OFFS(0), // Display offset + SH1106_START_LINE(0), // Start line + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_ADC_REVERSE(1), // Segment remap A0/A1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0x80), // Set contrast control + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period + SH1106_VCOM_DESEL(0x40), // Vcomh deselect level + SH1106_SCROLL(0), // Deactivate scroll + SH1106_ALL_PIX(0), // Output RAM to display + SH1106_INVERTED(0), // Normal display mode + SH1106_ON(1), // Display on + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +static const uint8_t u8g_dev_ssd1306_128x64_HAL_data_start[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_COL_ADR(0), // Column 0 + U8G_ESC_END // End of sequence +}; + +uint8_t u8g_dev_ssd1306_128x64_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { + switch(msg) { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_HAL_init_seq); + break; + case U8G_DEV_MSG_STOP: break; + case U8G_DEV_MSG_PAGE_NEXT: { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_HAL_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | pb->p.page); // Select current page (SSD1306) + u8g_SetAddress(u8g, dev, 1); // Data mode + if (u8g_pb_WriteBuffer(pb, u8g, dev) == 0) return 0; + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_off); + return 1; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteByte(u8g, dev, 0x81); + u8g_WriteByte(u8g, dev, *(uint8_t *) arg); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_ssd1306_128x64_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_128x64_HAL_fn, U8G_COM_HAL_SW_SPI_FN); + +#endif // U8GLIB_SSD1306_SPI +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp index 4aa90d5e8e82..010231d0561f 100644 --- a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp @@ -31,61 +31,83 @@ #define HEIGHT 64 #define PAGE_HEIGHT 8 +#define SSD1309_PAGE_ADR(N) (0x20), (N) +#define SSD1309_COL_ADR(N) (0x10 | ((N) >> 4)), ((N) & 0xFF) +#define SSD1309_COLUMN_RANGE(N,O) (0x21), (N), (O) +#define SSD1309_PAGE_RANGE(N,O) (0x22), (N), (O) +#define SSD1309_SCROLL(N) ((N) ? 0x2F : 0x2E) +#define SSD1309_START_LINE(N) (0x40 | (N)) +#define SSD1309_CONTRAST(N) (0x81), (N) +#define SSD1309_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) +#define SSD1309_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) +#define SSD1309_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) +#define SSD1309_INVERTED(N) ((N) ? 0xA7 : 0xA6) +#define SSD1309_MUX_RATIO(N) (0xA8), (N) +#define SSD1309_ON(N) ((N) ? 0xAF : 0xAE) +#define SSD1309_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) +#define SSD1309_DISP_OFFS(N) (0xD3), (N) +#define SSD1309_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) +#define SSD1309_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) +#define SSD1309_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) +#define SSD1309_VCOM_DESEL(N) (0xDB), (N) +#define SSD1309_NOOP() (0xE3) +#define SSD1309_COMMAND_LOCK(N) (0xFD), ((N) ? 0x16 : 0x12) + // SSD1309 init sequence static const uint8_t u8g_dev_ssd1309_128x64_init_seq[] PROGMEM = { - U8G_ESC_CS(0), // Disable chip - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds - U8G_ESC_CS(1), // Enable chip + U8G_ESC_CS(0), // Disable chip + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds + U8G_ESC_CS(1), // Enable chip + + SSD1309_COMMAND_LOCK(0), // Unlock OLED driver IC MCU command interface + SSD1309_ON(0), + SSD1309_OSC_FREQ(0, 10), // Clock divide ratio (0:1) and oscillator frequency (8) + SSD1309_MUX_RATIO(0x3F), // Mux ratio + SSD1309_DISP_OFFS(0), // Display offset + SSD1309_START_LINE(0), // Start line + SSD1309_ADC_REVERSE(1), // Segment remap A0/A1 + SSD1309_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SSD1309_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SSD1309_CONTRAST(0xDF), // Set contrast control + SSD1309_CHARGE_PER(0x2, 0x8), // Pre-charge period + SSD1309_VCOM_DESEL(0x34), // Vcomh deselect level + SSD1309_ALL_PIX(0), // Output RAM to display + SSD1309_INVERTED(0), // Normal display mode - 0xFD,0x12, // Command Lock - 0xAE, // Set Display Off - 0xD5,0xA0, // Set Display Clock Divide Ratio/Oscillator Frequency - 0xA8,0x3F, // Set Multiplex Ratio - 0x3D,0x00, // Set Display Offset - 0x40, // Set Display Start Line - 0xA1, // Set Segment Re-Map - 0xC8, // Set COM Output Scan Direction - 0xDA,0x12, // Set COM Pins Hardware Configuration - 0x81,0xDF, // Set Current Control - 0xD9,0x82, // Set Pre-Charge Period - 0xDB,0x34, // Set VCOMH Deselect Level - 0xA4, // Set Entire Display On/Off - 0xA6, // Set Normal/Inverse Display - U8G_ESC_VCC(1), // Power up VCC & Stabilized + U8G_ESC_VCC(1), // Power up VCC & stabilize U8G_ESC_DLY(50), - 0xAF, // Set Display On + SSD1309_ON(1), // Display on U8G_ESC_DLY(50), - U8G_ESC_CS(0), // Disable chip - U8G_ESC_END // End of sequence + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence }; // Select one init sequence here #define u8g_dev_ssd1309_128x64_init_seq u8g_dev_ssd1309_128x64_init_seq static const uint8_t u8g_dev_ssd1309_128x64_data_start[] PROGMEM = { - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_CS(1), // Enable chip - 0x010, // Set upper 4 bit of the col adr to 0 - 0x000, // Set lower 4 bit of the col adr to 4 - U8G_ESC_END // End of sequence + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SSD1309_COL_ADR(0), // Column 0 + U8G_ESC_END // End of sequence }; static const uint8_t u8g_dev_ssd13xx_sleep_on[] PROGMEM = { - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_CS(1), // Enable chip - 0x0AE, // Display off - U8G_ESC_CS(0), // Disable chip - U8G_ESC_END // End of sequence + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SSD1309_ON(0), // Display off + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence }; static const uint8_t u8g_dev_ssd13xx_sleep_off[] PROGMEM = { - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_CS(1), // Enable chip - 0x0AF, // Display on - U8G_ESC_DLY(50), // Delay 50 ms - U8G_ESC_CS(0), // Disable chip - U8G_ESC_END // End of sequence + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SSD1309_ON(1), // Display on + U8G_ESC_DLY(50), // Delay 50 ms + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence }; uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { @@ -99,7 +121,7 @@ uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void case U8G_DEV_MSG_PAGE_NEXT: { u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1309_128x64_data_start); - u8g_WriteByte(u8g, dev, 0x0B0 | pb->p.page); // Select current page (SSD1306) + u8g_WriteByte(u8g, dev, 0xB0 | pb->p.page); // Select current page (SSD1306) u8g_SetAddress(u8g, dev, 1); // Data mode if (u8g_pb_WriteBuffer(pb, u8g, dev) == 0) return 0; u8g_SetChipSelect(u8g, dev, 0); @@ -108,8 +130,8 @@ uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void case U8G_DEV_MSG_CONTRAST: u8g_SetChipSelect(u8g, dev, 1); u8g_SetAddress(u8g, dev, 0); // Instruction mode - u8g_WriteByte(u8g, dev, 0x081); - u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) ); // 11 Jul 2015: fixed contrast calculation + u8g_WriteByte(u8g, dev, 0x81); + u8g_WriteByte(u8g, dev, (*(uint8_t *)arg)); u8g_SetChipSelect(u8g, dev, 0); return 1; case U8G_DEV_MSG_SLEEP_ON: diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp index 95ae2810f256..f9c68c15fc15 100644 --- a/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp @@ -130,7 +130,7 @@ static const uint8_t u8g_dev_uc1701_mini12864_HAL_data_start[] PROGMEM = { UC1701_V5_RATIO(3), // set V0 voltage resistor ratio to large UC1701_INDICATOR(0), // indicator disable UC1701_ON(1), // display on - UC1701_COLUMN_HI(0), // set upper 4 bit of the col adr to 0 + UC1701_COLUMN_HI(0), // set upper 4 bits of the col adr to 0 U8G_ESC_END, // end of sequence U8G_ESC_DLY(5) // delay 5 ms #else diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp index d78364cb3bc1..8e2b1bb8e48a 100644 --- a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp +++ b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp @@ -69,7 +69,7 @@ void MKS_reset_settings() { { 20, 20 }, { 20, 20 }, { X_CENTER, Y_CENTER } }; - mks_language_index = MKS_SimpleChinese; + mks_language_index = MKS_English; COPY(mks_corner_offsets, init_dgus_level_offsets); mks_park_pos.set(20, 20, 10); mks_min_extrusion_temp = 0; diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp index dc80a7aed02b..118cfd35143b 100644 --- a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp +++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp @@ -101,7 +101,7 @@ void DGUSRxHandler::retractLength(DGUS_VP &vp, void *data) { void DGUSRxHandler::setLanguage(DGUS_VP &vp, void *data) { DGUS_Data::Language language = (DGUS_Data::Language)Endianness::fromBE_P(data); - ui_language = screen.config.language = language; + screen.config.language = language; screen.triggerEEPROMSave(); screen.triggerFullUpdate(); } diff --git a/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp b/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp index 345c5dd732c0..ee913d646548 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp @@ -294,7 +294,7 @@ void setProBarRate() { lv_label_set_text(bar1ValueText, public_buf_l); lv_obj_align(bar1ValueText, bar1, LV_ALIGN_CENTER, 0, 0); - if (marlin_state == MF_SD_COMPLETE) { + if (marlin_state == MarlinState::MF_SD_COMPLETE) { if (once_flag == 0) { stop_print_time(); @@ -309,7 +309,7 @@ void setProBarRate() { if (gCfgItems.finish_power_off) { gcode.process_subcommands_now(F("M1001")); queue.inject(F("M81")); - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; } #endif } diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp index 7408197f73fe..bd06e6c1f482 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp @@ -766,7 +766,7 @@ void GUI_RefreshPage() { disp_print_time(); disp_fan_Zpos(); } - if (printing_rate_update_flag || marlin_state == MF_SD_COMPLETE) { + if (printing_rate_update_flag || marlin_state == MarlinState::MF_SD_COMPLETE) { printing_rate_update_flag = false; if (!gcode_preview_over) setProBarRate(); } diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index 1fcfabdd7257..d89a09d8ada2 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -1219,7 +1219,7 @@ namespace ExtUI { void onSurviveInKilled() { thermalManager.disable_all_heaters(); flags.printer_killed = 0; - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; //SERIAL_ECHOLNPGM("survived at: ", millis()); } diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index a967d921359f..8b24cd26eb46 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -25,7 +25,7 @@ #include "../MarlinCore.h" // for printingIsPaused #include "../gcode/parser.h" // for axis_is_rotational, using_inch_units -#if LED_POWEROFF_TIMEOUT > 0 || ALL(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) || (HAS_BACKLIGHT_TIMEOUT && defined(NEOPIXEL_BKGD_INDEX_FIRST)) +#if HAS_LED_POWEROFF_TIMEOUT || ALL(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) || (HAS_BACKLIGHT_TIMEOUT && defined(NEOPIXEL_BKGD_INDEX_FIRST)) #include "../feature/leds/leds.h" #endif @@ -319,7 +319,7 @@ void MarlinUI::init() { #include "../feature/power_monitor.h" #endif - #if LED_POWEROFF_TIMEOUT > 0 + #if HAS_LED_POWEROFF_TIMEOUT #include "../feature/power.h" #endif @@ -943,9 +943,7 @@ void MarlinUI::init() { static uint16_t max_display_update_time = 0; const millis_t ms = millis(); - #if LED_POWEROFF_TIMEOUT > 0 - leds.update_timeout(powerManager.psu_on); - #endif + TERN_(HAS_LED_POWEROFF_TIMEOUT, leds.update_timeout(powerManager.psu_on)); #if HAS_MARLINUI_MENU @@ -1085,10 +1083,8 @@ void MarlinUI::init() { refresh(LCDVIEW_REDRAW_NOW); - #if LED_POWEROFF_TIMEOUT > 0 - if (!powerManager.psu_on) leds.reset_timeout(ms); - #endif - } // encoder activity + TERN_(HAS_LED_POWEROFF_TIMEOUT, if (!powerManager.psu_on) leds.reset_timeout(ms)); + } // encoder or click #endif // HAS_ENCODER_ACTION @@ -1828,13 +1824,14 @@ void MarlinUI::host_notify(const char * const cstr) { #endif void MarlinUI::media_changed(const uint8_t old_status, const uint8_t status) { + TERN_(HAS_DISPLAY_SLEEP, refresh_screen_timeout()); if (old_status == status) { TERN_(EXTENSIBLE_UI, ExtUI::onMediaError()); // Failed to mount/unmount return; } - if (status) { - if (old_status < 2) { + if (old_status < 2) { // Skip this section on first boot check + if (status) { // Media Mounted #if ENABLED(EXTENSIBLE_UI) ExtUI::onMediaMounted(); #elif ENABLED(BROWSE_MEDIA_ON_INSERT) @@ -1845,16 +1842,16 @@ void MarlinUI::host_notify(const char * const cstr) { LCD_MESSAGE(MSG_MEDIA_INSERTED); #endif } - } - else { - if (old_status < 2) { + else { // Media Removed #if ENABLED(EXTENSIBLE_UI) ExtUI::onMediaRemoved(); - #elif HAS_SD_DETECT + #elif HAS_SD_DETECT // Q: Does "Media Removed" need to be shown for manual release too? LCD_MESSAGE(MSG_MEDIA_REMOVED); #if HAS_MARLINUI_MENU - if (!defer_return_to_status) return_to_status(); + if (ENABLED(HAS_WIRED_LCD) || !defer_return_to_status) return_to_status(); #endif + #elif HAS_WIRED_LCD + return_to_status(); #endif } } @@ -1863,14 +1860,10 @@ void MarlinUI::host_notify(const char * const cstr) { refresh(); - #if HAS_WIRED_LCD || LED_POWEROFF_TIMEOUT > 0 + #if HAS_WIRED_LCD || HAS_LED_POWEROFF_TIMEOUT const millis_t ms = millis(); - #endif - - TERN_(HAS_WIRED_LCD, next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL); // Delay LCD update for SD activity - - #if LED_POWEROFF_TIMEOUT > 0 - leds.reset_timeout(ms); + TERN_(HAS_WIRED_LCD, next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL); // Delay LCD update for SD activity + TERN_(HAS_LED_POWEROFF_TIMEOUT, leds.reset_timeout(ms)); #endif } diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index cc130327a96b..14bf42700f2c 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -304,6 +304,7 @@ class MarlinUI { static void refresh_screen_timeout(); #endif + // Sleep or wake the display (e.g., by turning the backlight off/on). static void sleep_display(const bool=true) IF_DISABLED(HAS_DISPLAY_SLEEP, {}); static void wake_display() { sleep_display(false); } @@ -743,7 +744,7 @@ class MarlinUI { static void draw_select_screen_prompt(FSTR_P const fpre, const char * const string=nullptr, FSTR_P const fsuf=nullptr); - #else + #else // !HAS_MARLINUI_MENU static void return_to_status() {} @@ -753,7 +754,7 @@ class MarlinUI { FORCE_INLINE static void run_current_screen() { status_screen(); } #endif - #endif + #endif // !HAS_MARLINUI_MENU #if ANY(HAS_MARLINUI_MENU, EXTENSIBLE_UI) static bool lcd_clicked; diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index b7825949c07a..903c857f59f4 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -700,7 +700,7 @@ void menu_advanced_settings() { // M593 - Acceleration items #if ENABLED(SHAPING_MENU) - if (!is_busy) SUBMENU(MSG_INPUT_SHAPING, menu_advanced_input_shaping); + SUBMENU(MSG_INPUT_SHAPING, menu_advanced_input_shaping); #endif #if ENABLED(CLASSIC_JERK) diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index e7786749b5fc..e9aafa49c847 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -1307,7 +1307,7 @@ void Endstops::update() { ES_REPORT_CHANGE(Z_MIN_PROBE); #endif #if USE_CALIBRATION - ES_REPORT_STATE(CALIBRATION); + ES_REPORT_CHANGE(CALIBRATION); #endif #if USE_X2_MIN ES_REPORT_CHANGE(X2_MIN); diff --git a/Marlin/src/module/endstops.h b/Marlin/src/module/endstops.h index 7a6da5eefa8a..1a76a26a3fe9 100644 --- a/Marlin/src/module/endstops.h +++ b/Marlin/src/module/endstops.h @@ -31,7 +31,7 @@ #define _ES_ENUM(A,M) A##_##M #define ES_ENUM(A,M) _ES_ENUM(A,M) -#define _ES_ITEM(N) N, +#define _ES_ITEM(N) , N #define ES_ITEM(K,N) TERN(K,_ES_ITEM,_IF_1_ELSE)(N) #define _ESN_ITEM(K,A,M) ES_ITEM(K,ES_ENUM(A,M)) @@ -57,7 +57,9 @@ * - Z_MIN_PROBE is an alias to Z_MIN when the Z_MIN_PIN is being used as the probe pin. * - When homing with the probe Z_ENDSTOP is a Z_MIN_PROBE alias, otherwise a Z_MIN/MAX alias. */ -enum EndstopEnum : char { +enum EndstopEnum : int8_t { + _ES_START_ = -1 + // Common XYZ (ABC) endstops. ES_MINMAX(X) ES_MINMAX(Y) ES_MINMAX(Z) ES_MINMAX(I) ES_MINMAX(J) ES_MINMAX(K) @@ -70,12 +72,18 @@ enum EndstopEnum : char { ES_ITEM(HAS_CALIBRATION_STATE, CALIBRATION) // Bed Probe state is distinct or shared with Z_MIN (i.e., when the probe is the only Z endstop) - ES_ITEM(HAS_Z_PROBE_STATE, Z_MIN_PROBE IF_DISABLED(USE_Z_MIN_PROBE, = Z_MIN)) + #if HAS_Z_PROBE_STATE && USE_Z_MIN_PROBE + , Z_MIN_PROBE + #endif - // The total number of states - NUM_ENDSTOP_STATES + // The total number of distinct states + , NUM_ENDSTOP_STATES // Endstop aliases + #if HAS_Z_PROBE_STATE && !USE_Z_MIN_PROBE + , Z_MIN_PROBE = Z_MIN + #endif + #if HAS_X_STATE , X_ENDSTOP = TERN(X_HOME_TO_MAX, X_MAX, X_MIN) #endif @@ -88,7 +96,6 @@ enum EndstopEnum : char { #if HAS_Y2_STATE , Y2_ENDSTOP = TERN(Y_HOME_TO_MAX, Y2_MAX, Y2_MIN) #endif - #if HOMING_Z_WITH_PROBE , Z_ENDSTOP = Z_MIN_PROBE // "Z" endstop alias when homing with the probe #elif HAS_Z_STATE @@ -258,7 +265,7 @@ class Endstops { #if ENABLED(CALIBRATION_GCODE) static volatile bool calibration_probe_enabled; static volatile bool calibration_stop_state; - static void enable_calibration_probe(const bool onoff,const bool stop_state = true); + static void enable_calibration_probe(const bool onoff, const bool stop_state=true); #endif static void resync(); diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 473d54cc382b..4bbb182bc345 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -257,7 +257,7 @@ void report_current_position_projected() { AutoReporter position_auto_reporter; #endif -#if ANY(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) +#if ENABLED(REALTIME_REPORTING_COMMANDS) M_StateEnum M_State_grbl = M_INIT; @@ -299,18 +299,18 @@ void report_current_position_projected() { */ M_StateEnum grbl_state_for_marlin_state() { switch (marlin_state) { - case MF_INITIALIZING: return M_INIT; - case MF_SD_COMPLETE: return M_ALARM; - case MF_WAITING: return M_IDLE; - case MF_STOPPED: return M_END; - case MF_RUNNING: return M_RUNNING; - case MF_PAUSED: return M_HOLD; - case MF_KILLED: return M_ERROR; - default: return M_IDLE; + case MarlinState::MF_INITIALIZING: return M_INIT; + case MarlinState::MF_SD_COMPLETE: return M_ALARM; + case MarlinState::MF_WAITING: return M_IDLE; + case MarlinState::MF_STOPPED: return M_END; + case MarlinState::MF_RUNNING: return M_RUNNING; + case MarlinState::MF_PAUSED: return M_HOLD; + case MarlinState::MF_KILLED: return M_ERROR; + default: return M_IDLE; } } -#endif +#endif // REALTIME_REPORTING_COMMANDS #if IS_KINEMATIC diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index f9748871f5c8..bb8f36446b0c 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -272,7 +272,7 @@ void report_current_position_projected(); extern AutoReporter position_auto_reporter; #endif -#if ANY(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) +#if ENABLED(REALTIME_REPORTING_COMMANDS) #define HAS_GRBL_STATE 1 /** * Machine states for GRBL or TinyG @@ -305,11 +305,9 @@ void report_current_position_projected(); } #endif - #if ENABLED(REALTIME_REPORTING_COMMANDS) - void quickpause_stepper(); - void quickresume_stepper(); - #endif -#endif + void quickpause_stepper(); + void quickresume_stepper(); +#endif // REALTIME_REPORTING_COMMANDS float get_move_distance(const xyze_pos_t &diff OPTARG(HAS_ROTATIONAL_AXES, bool &is_cartesian_move)); diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index b4546e0235bf..b3dc856a0a58 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -729,8 +729,6 @@ void Planner::init() { #endif #endif -#define MINIMAL_STEP_RATE 120 - /** * Get the current block for processing * and mark the block as busy. @@ -796,13 +794,9 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t uint32_t initial_rate = entry_speed ? LROUND(entry_speed * spmm) : block->initial_rate, final_rate = LROUND(exit_speed * spmm); - // Removing code to constrain values produces judder in direction-switching moves because the - // current discrete stepping math diverges from physical motion under constant acceleration - // when acceleration_steps_per_s2 is large compared to initial/final_rate. - NOLESS(initial_rate, long(MINIMAL_STEP_RATE)); - NOLESS(final_rate, long(MINIMAL_STEP_RATE)); - NOMORE(initial_rate, block->nominal_rate); // NOTE: The nominal rate may be less than MINIMAL_STEP_RATE! - NOMORE(final_rate, block->nominal_rate); + NOLESS(initial_rate, stepper.minimal_step_rate); + NOLESS(final_rate, stepper.minimal_step_rate); + NOLESS(block->nominal_rate, stepper.minimal_step_rate); #if ANY(S_CURVE_ACCELERATION, LIN_ADVANCE) // If we have some plateau time, the cruise rate will be the nominal rate @@ -1201,16 +1195,20 @@ void Planner::recalculate(const_float_t safe_exit_speed_sqr) { void Planner::kickstart_fan(uint8_t (&fan_speed)[FAN_COUNT], const millis_t &ms, const uint8_t f) { static millis_t fan_kick_end[FAN_COUNT] = { 0 }; + #if ENABLED(FAN_KICKSTART_LINEAR) + static uint8_t set_fan_speed[FAN_COUNT] = { 0 }; + #endif if (fan_speed[f] > FAN_OFF_PWM) { - if (fan_kick_end[f] == 0) { - fan_kick_end[f] = ms + FAN_KICKSTART_TIME; + const bool first_kick = fan_kick_end[f] == 0 && TERN1(FAN_KICKSTART_LINEAR, fan_speed[f] > set_fan_speed[f]); + if (first_kick) + fan_kick_end[f] = ms + (FAN_KICKSTART_TIME) TERN_(FAN_KICKSTART_LINEAR, * (fan_speed[f] - set_fan_speed[f]) / 255); + if (first_kick || PENDING(ms, fan_kick_end[f])) { fan_speed[f] = FAN_KICKSTART_POWER; + return; } - else if (PENDING(ms, fan_kick_end[f])) - fan_speed[f] = FAN_KICKSTART_POWER; } - else - fan_kick_end[f] = 0; + fan_kick_end[f] = 0; + TERN_(FAN_KICKSTART_LINEAR, set_fan_speed[f] = fan_speed[f]); } #endif diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index d4467b76877d..a553d56745ad 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -1823,7 +1823,7 @@ void MarlinSettings::postprocess() { EEPROM_Error eeprom_error = ERR_EEPROM_NOERR; const EEPROM_Error check = check_version(); - if (check == ERR_EEPROM_VERSION) return eeprom_error; + if (check == ERR_EEPROM_NOPROM) return eeprom_error; uint16_t stored_crc; diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index f5a9f6d0a8ae..9da12dee1186 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -2201,12 +2201,10 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) { #ifdef CPU_32_BIT // A fast processor can just do integer division - constexpr uint32_t min_step_rate = uint32_t(STEPPER_TIMER_RATE) / HAL_TIMER_TYPE_MAX; - return step_rate > min_step_rate ? uint32_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX; + return step_rate > minimal_step_rate ? uint32_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX; #else - constexpr uint32_t min_step_rate = (F_CPU) / 500000U; // i.e., 32 or 40 if (step_rate >= 0x0800) { // higher step rate // AVR is able to keep up at around 65kHz Stepping ISR rate at most. // So values for step_rate > 65535 might as well be truncated. @@ -2220,8 +2218,8 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) { const uint8_t gain = uint8_t(pgm_read_byte(table_address + 2)); return base - MultiU8X8toH8(uint8_t(step_rate & 0x00FF), gain); } - else if (step_rate > min_step_rate) { // lower step rates - step_rate -= min_step_rate; // Correct for minimal speed + else if (step_rate > minimal_step_rate) { // lower step rates + step_rate -= minimal_step_rate; // Correct for minimal speed const uintptr_t table_address = uintptr_t(&speed_lookuptable_slow[uint8_t(step_rate >> 3)]); return uint16_t(pgm_read_word(table_address)) - ((uint16_t(pgm_read_word(table_address + 2)) * uint8_t(step_rate & 0x0007)) >> 3); diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 3586c23e7060..2a171bebd0be 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -295,6 +295,16 @@ class Stepper { public: + // The minimal step rate ensures calculations stay within limits + // and avoid the most unreasonably slow step rates. + static constexpr uint32_t minimal_step_rate = ( + #ifdef CPU_32_BIT + _MAX((STEPPER_TIMER_RATE) / HAL_TIMER_TYPE_MAX, 1U) // 32-bit shouldn't go below 1 + #else + (F_CPU) / 500000U // AVR shouldn't go below 32 (16MHz) or 40 (20MHz) + #endif + ); + #if ANY(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) static bool separate_multi_axis; #endif diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 16b43f62f098..1b8ebeea6964 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -1430,7 +1430,7 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { // inline void loud_kill(FSTR_P const lcd_msg, const heater_id_t heater_id) { - marlin_state = MF_KILLED; + marlin_state = MarlinState::MF_KILLED; thermalManager.disable_all_heaters(); #if HAS_BEEPER for (uint8_t i = 20; i--;) { @@ -2077,7 +2077,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T * - Update the heated bed PID output value */ void Temperature::task() { - if (marlin_state == MF_INITIALIZING) return hal.watchdog_refresh(); // If Marlin isn't started, at least reset the watchdog! + if (marlin_state == MarlinState::MF_INITIALIZING) return hal.watchdog_refresh(); // If Marlin isn't started, at least reset the watchdog! static bool no_reentry = false; // Prevent recursion if (no_reentry) return; diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index a9349910d79c..1a356b17d785 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -564,15 +564,15 @@ #elif MB(BTT_SKR_MINI_E3_V3_0) #include "stm32g0/pins_BTT_SKR_MINI_E3_V3_0.h" // STM32G0 env:STM32G0B1RE_btt env:STM32G0B1RE_btt_xfer #elif MB(BTT_MANTA_M4P_V2_1) - #include "stm32g0/pins_BTT_MANTA_M4P_V2_1.h" // STM32G0 env:STM32G0B1RE_manta_btt env:STM32G0B1RE_manta_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M4P_V2_1.h" // STM32G0 env:STM32G0B1RE_manta_btt #elif MB(BTT_MANTA_M5P_V1_0) - #include "stm32g0/pins_BTT_MANTA_M5P_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt env:STM32G0B1RE_manta_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M5P_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt #elif MB(BTT_MANTA_E3_EZ_V1_0) - #include "stm32g0/pins_BTT_MANTA_E3_EZ_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt env:STM32G0B1RE_manta_btt_xfer + #include "stm32g0/pins_BTT_MANTA_E3_EZ_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt #elif MB(BTT_MANTA_M8P_V1_0) - #include "stm32g0/pins_BTT_MANTA_M8P_V1_0.h" // STM32G0 env:STM32G0B1VE_btt env:STM32G0B1VE_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M8P_V1_0.h" // STM32G0 env:STM32G0B1VE_btt #elif MB(BTT_MANTA_M8P_V1_1) - #include "stm32g0/pins_BTT_MANTA_M8P_V1_1.h" // STM32G0 env:STM32G0B1VE_btt env:STM32G0B1VE_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M8P_V1_1.h" // STM32G0 env:STM32G0B1VE_btt // // STM32 ARM Cortex-M3 @@ -980,8 +980,6 @@ #error "BOARD_BIQU_SKR_V1_1 is now BOARD_BTT_SKR_V1_1. Please update your configuration." #elif MB(BIGTREE_SKR_V1_1) #error "BOARD_BIGTREE_SKR_V1_1 is now BOARD_BTT_SKR_V1_1. Please update your configuration." - #elif MB(BIGTREE_SKR_V1_2) - #error "BOARD_BIGTREE_SKR_V1_2 is now BOARD_BTT_SKR_V1_2. Please update your configuration." #elif MB(BIGTREE_SKR_V1_3) #error "BOARD_BIGTREE_SKR_V1_3 is now BOARD_BTT_SKR_V1_3. Please update your configuration." #elif MB(BIGTREE_SKR_V1_4) diff --git a/Marlin/src/pins/ramps/pins_MKS_BASE_14.h b/Marlin/src/pins/ramps/pins_MKS_BASE_14.h index 9877877ffdfa..43644a4506fe 100644 --- a/Marlin/src/pins/ramps/pins_MKS_BASE_14.h +++ b/Marlin/src/pins/ramps/pins_MKS_BASE_14.h @@ -43,10 +43,10 @@ #ifndef RGB_LED_R_PIN #define RGB_LED_R_PIN 50 #endif -#ifndef RGB_LED_R_PIN +#ifndef RGB_LED_G_PIN #define RGB_LED_G_PIN 51 #endif -#ifndef RGB_LED_R_PIN +#ifndef RGB_LED_B_PIN #define RGB_LED_B_PIN 52 #endif diff --git a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h index a256d2e7cb26..cf400335f531 100644 --- a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h +++ b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h @@ -206,3 +206,6 @@ #define INDEX_AUX3_PWM2 PB9 #define INDEX_AUX3_A1 PA0 #define INDEX_AUX3_A2 PA1 + +#define RS485_TX_ENABLE_PIN PD11 +#define RS485_RX_ENABLE_PIN PD12 diff --git a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h index f7daa4c3ec41..9c374eae4444 100644 --- a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h +++ b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h @@ -206,3 +206,6 @@ #define LUMEN_AUX3_PWM2 PB9 #define LUMEN_AUX3_A1 PA0 #define LUMEN_AUX3_A2 PA1 + +#define RS485_TX_ENABLE_PIN PD11 +#define RS485_RX_ENABLE_PIN PD12 diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 14319940931b..c13ba37a96ef 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -497,7 +497,7 @@ void CardReader::mount() { cdroot(); else { #if ANY(HAS_SD_DETECT, USB_FLASH_DRIVE_SUPPORT) - if (marlin_state != MF_INITIALIZING) LCD_ALERTMESSAGE(MSG_MEDIA_INIT_FAIL); + if (marlin_state != MarlinState::MF_INITIALIZING) LCD_ALERTMESSAGE(MSG_MEDIA_INIT_FAIL); #endif } @@ -1412,8 +1412,8 @@ void CardReader::fileHasFinished() { endFilePrintNow(TERN_(SD_RESORT, true)); - flag.sdprintdone = true; // Stop getting bytes from the SD card - marlin_state = MF_SD_COMPLETE; // Tell Marlin to enqueue M1001 soon + flag.sdprintdone = true; // Stop getting bytes from the SD card + marlin_state = MarlinState::MF_SD_COMPLETE; // Tell Marlin to enqueue M1001 soon } #if ENABLED(AUTO_REPORT_SD_STATUS) diff --git a/README.md b/README.md index b11a1193b976..77a23eaf2f70 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Every new HAL opens up a world of hardware. At this time we need HALs for RP2040 [Teensy 4.0](https://www.pjrc.com/store/teensy40.html)|ARM® Cortex-M7| [Teensy 4.1](https://www.pjrc.com/store/teensy41.html)|ARM® Cortex-M7| Linux Native|x86/ARM/etc.|Raspberry Pi + [All supported boards](https://marlinfw.org/docs/hardware/boards.html#boards-list)|All platforms|All boards ## Marlin Support diff --git a/buildroot/share/PlatformIO/scripts/preflight-checks.py b/buildroot/share/PlatformIO/scripts/preflight-checks.py index 731537f3ed85..307c2fb33f33 100644 --- a/buildroot/share/PlatformIO/scripts/preflight-checks.py +++ b/buildroot/share/PlatformIO/scripts/preflight-checks.py @@ -78,12 +78,15 @@ def sanity_check_target(): ( build_env, motherboard, ", ".join([ e[4:] for e in board_envs if e.startswith("env:") ]) ) raise SystemExit(err) + # Useful values + project_dir = Path(env['PROJECT_DIR']) + config_files = ("Configuration.h", "Configuration_adv.h") + # # Check for Config files in two common incorrect places # - epath = Path(env['PROJECT_DIR']) - for p in [ epath, epath / "config" ]: - for f in ("Configuration.h", "Configuration_adv.h"): + for p in (project_dir, project_dir / "config"): + for f in config_files: if (p / f).is_file(): err = "ERROR: Config files found in directory %s. Please move them into the Marlin subfolder." % p raise SystemExit(err) @@ -114,11 +117,11 @@ def rm_ofile(subdir, name): # Check for old files indicating an entangled Marlin (mixing old and new code) # mixedin = [] - p = Path(env['PROJECT_DIR'], "Marlin/src/lcd/dogm") + p = project_dir / "Marlin/src/lcd/dogm" for f in [ "ultralcd_DOGM.cpp", "ultralcd_DOGM.h" ]: if (p / f).is_file(): mixedin += [ f ] - p = Path(env['PROJECT_DIR'], "Marlin/src/feature/bedlevel/abl") + p = project_dir / "Marlin/src/feature/bedlevel/abl" for f in [ "abl.cpp", "abl.h" ]: if (p / f).is_file(): mixedin += [ f ] @@ -137,4 +140,22 @@ def rm_ofile(subdir, name): err = "ERROR: FILAMENT_RUNOUT_SCRIPT needs a %c parameter (e.g., \"M600 T%c\") when NUM_RUNOUT_SENSORS is > 1" raise SystemExit(err) + # + # Update old macros BOTH and EITHER in configuration files + # + conf_modified = False + for f in config_files: + conf_path = project_dir / "Marlin" / f + if conf_path.is_file(): + with open(conf_path, 'r', encoding="utf8") as file: + text = file.read() + modified_text = text.replace("BOTH(", "ALL(").replace("EITHER(", "ANY(") + if text != modified_text: + conf_modified = True + with open(conf_path, 'w') as file: + file.write(modified_text) + + if conf_modified: + raise SystemExit('WARNING: Configuration files needed an update to remove incompatible items. Try the build again to use the updated files.') + sanity_check_target() diff --git a/buildroot/tests/Opulo_Lumen_REV3 b/buildroot/tests/Opulo_Lumen_REV3 index f12f69011e78..436a71e64418 100755 --- a/buildroot/tests/Opulo_Lumen_REV3 +++ b/buildroot/tests/Opulo_Lumen_REV3 @@ -8,6 +8,7 @@ set -e use_example_configs Opulo/Lumen_REV3 opt_disable TMC_DEBUG +opt_set RS485_SERIAL_PORT 2 RS485_BUS_BUFFER_SIZE 128 exec_test $1 $2 "Opulo Lumen REV3 Pick-and-Place" "$3" # cleanup diff --git a/ini/features.ini b/ini/features.ini index b81c5285bf0b..375c26ffb782 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -12,7 +12,7 @@ # The order of the features matters for source-filter resolution inside of common-dependencies.py. [features] -YHCB2004 = red-scorp/LiquidCrystal_AIP31068@^1.0.4, red-scorp/SoftSPIB@^1.1.1 +YHCB2004 = LiquidCrystal_AIP31068=https://github.com/ellensp/LiquidCrystal_AIP31068/archive/3fc43b7.zip, red-scorp/SoftSPIB@^1.1.1 HAS_TFT_LVGL_UI = lvgl=https://github.com/makerbase-mks/LVGL-6.1.1-MKS/archive/a3ebe98bc6.zip build_src_filter=+ extra_scripts=download_mks_assets.py @@ -23,7 +23,6 @@ MKS_WIFI_MODULE = QRCode=https://github.com/makerbase-mks HAS_TRINAMIC_CONFIG = TMCStepper@~0.7.3 build_src_filter=+ + + + + HAS_T(RINAMIC_CONFIG|MC_SPI) = build_src_filter=+ -HAS_STEALTHCHOP = build_src_filter=+ SR_LCD_3W_NL = SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/6f53c19a8a.zip HAS_MOTOR_CURRENT_(I2C|DAC|SPI|PWM) = build_src_filter=+ HAS_MOTOR_CURRENT_I2C = SlowSoftI2CMaster @@ -317,6 +316,7 @@ NONLINEAR_EXTRUSION = build_src_filter=+ + PARK_HEAD_ON_PAUSE = build_src_filter=+ FILAMENT_LOAD_UNLOAD_GCODES = build_src_filter=+ +HAS_STEALTHCHOP = build_src_filter=+ CNC_WORKSPACE_PLANES = build_src_filter=+ CNC_COORDINATE_SYSTEMS = build_src_filter=+ HAS_HOME_OFFSET = build_src_filter=+ @@ -334,6 +334,8 @@ HAS_LCD_CONTRAST = build_src_filter=+ HAS_LCD_BRIGHTNESS = build_src_filter=+ HAS_SOUND = build_src_filter=+ +HAS_RS485_SERIAL = jnesselr/rs485@^0.0.9 + build_src_filter=+ + HAS_MULTI_LANGUAGE = build_src_filter=+ TOUCH_SCREEN_CALIBRATION = build_src_filter=+ ARC_SUPPORT = build_src_filter=+ diff --git a/ini/renamed.ini b/ini/renamed.ini index 85f2df286273..5540374c685e 100644 --- a/ini/renamed.ini +++ b/ini/renamed.ini @@ -98,3 +98,9 @@ extends = renamed [env:STM32F446_tronxy] ;=> TRONXY_CXY_446_V10 extends = renamed + +[env:STM32G0B1RE_manta_btt_xfer] ;=> STM32G0B1RE_manta_btt +extends = renamed + +[env:STM32G0B1VE_btt_xfer] ;=> STM32G0B1VE_btt +extends = renamed diff --git a/ini/stm32g0.ini b/ini/stm32g0.ini index 77bdde7438dd..40493b3ff1e5 100644 --- a/ini/stm32g0.ini +++ b/ini/stm32g0.ini @@ -88,21 +88,6 @@ extends = env:STM32G0B1RE_btt build_flags = ${env:STM32G0B1RE_btt.build_flags} -DPIN_SERIAL3_RX=PD_9 -DPIN_SERIAL3_TX=PD_8 -DENABLE_HWSERIAL3 -# -# BigTreeTech Manta M4P V2.1 (STM32G0B0RET6 ARM Cortex-M0+) -# BigTreeTech Manta E3 EZ V1.0 / Manta M5P V1.0 (STM32G0B1RET6 ARM Cortex-M0+) -# Custom upload to SD via Marlin with Binary Protocol -# Requires Marlin with BINARY_FILE_TRANSFER already installed on the target board. -# If CUSTOM_FIRMWARE_UPLOAD is also installed, Marlin will reboot the board to install the firmware. -# Currently CUSTOM_FIRMWARE_UPLOAD must also be enabled to use 'xfer' build envs. -# -[env:STM32G0B1RE_manta_btt_xfer] -extends = env:STM32G0B1RE_manta_btt -build_flags = ${env:STM32G0B1RE_manta_btt.build_flags} -DXFER_BUILD -extra_scripts = ${env:STM32G0B1RE_manta_btt.extra_scripts} - pre:buildroot/share/scripts/upload.py -upload_protocol = custom - # # BigTreeTech Manta M8P V1.x (STM32G0B1VET6 ARM Cortex-M0+) # @@ -123,14 +108,3 @@ build_flags = ${stm32_variant.build_flags} -Wl,--no-warn-rwx-segment upload_protocol = stlink debug_tool = stlink - -# -# BigTreeTech Manta M8P V1.x (STM32G0B1VET6 ARM Cortex-M0+) -# Custom upload to SD via Marlin with Binary Protocol -# -[env:STM32G0B1VE_btt_xfer] -extends = env:STM32G0B1VE_btt -build_flags = ${env:STM32G0B1VE_btt.build_flags} -DXFER_BUILD -extra_scripts = ${env:STM32G0B1VE_btt.extra_scripts} - pre:buildroot/share/scripts/upload.py -upload_protocol = custom