Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ef7509808f | ||
|
334f8874cf | ||
|
08650e69e2 | ||
|
e48bc01dbc | ||
|
88a2ac92d5 | ||
|
3ccb3801f2 | ||
|
cc7fbabc96 | ||
|
28a9708ddb | ||
|
d896dedf9b | ||
|
00709017e2 | ||
|
b7d9b05952 | ||
|
f7f1224941 | ||
|
fd8d83b7c8 | ||
|
52fc0b896d | ||
|
ba045d6852 | ||
|
54bdcb4691 | ||
|
2a2666326b | ||
|
3bba5d55bf | ||
|
5d07d83e78 | ||
|
37f97bc013 | ||
|
6d31bbe2bf | ||
|
e2e1776a14 | ||
|
bd196e7efc | ||
|
dffe7b9072 | ||
|
2b326ebc84 | ||
|
f4ff6a673f | ||
|
cc915a25ed | ||
|
600870f22b | ||
|
04882e2f34 | ||
|
c6cf3da276 | ||
|
8a5c3782b8 | ||
|
beb17d8855 | ||
|
4ee717f7c4 | ||
|
e680196c59 | ||
|
ce92abfe47 | ||
|
50410aaeaa | ||
|
35c40bc376 | ||
|
aae644c507 | ||
|
ce830f8a71 | ||
|
d3d423a322 | ||
|
8b060a3902 | ||
|
faae900747 |
110
.gitignore
vendored
110
.gitignore
vendored
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Marlin 3D Printer Firmware
|
||||
# Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
# Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
#
|
||||
# Based on Sprinter and grbl.
|
||||
# Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
@@ -19,34 +19,23 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# Our automatic versioning scheme generates the following file
|
||||
# NEVER put it in the repository
|
||||
# Generated files
|
||||
_Version.h
|
||||
bdf2u8g.exe
|
||||
genpages.exe
|
||||
marlin_config.json
|
||||
mczip.h
|
||||
language*.csv
|
||||
out-csv/
|
||||
out-language/
|
||||
*.gen
|
||||
*.sublime-workspace
|
||||
|
||||
#
|
||||
# OS
|
||||
#
|
||||
applet/
|
||||
*.DS_Store
|
||||
.DS_Store
|
||||
|
||||
#
|
||||
# Misc
|
||||
#
|
||||
*~
|
||||
*.orig
|
||||
*.rej
|
||||
*.bak
|
||||
*.idea
|
||||
*.s
|
||||
*.i
|
||||
*.ii
|
||||
*.swp
|
||||
tags
|
||||
|
||||
#
|
||||
# C++
|
||||
#
|
||||
# Compiled Object files
|
||||
# Compiled C++ Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
@@ -77,11 +66,7 @@ tags
|
||||
*.out
|
||||
*.app
|
||||
|
||||
|
||||
#
|
||||
# C
|
||||
#
|
||||
# Object files
|
||||
# Compiled C Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
@@ -123,33 +108,10 @@ tags
|
||||
.gcc-flags.json
|
||||
/lib/
|
||||
|
||||
# Workaround for Deviot+platformio quirks
|
||||
Marlin/lib
|
||||
Marlin/platformio.ini
|
||||
Marlin/*/platformio.ini
|
||||
Marlin/*/*/platformio.ini
|
||||
Marlin/*/*/*/platformio.ini
|
||||
Marlin/*/*/*/*/platformio.ini
|
||||
Marlin/.travis.yml
|
||||
Marlin/*/.travis.yml
|
||||
Marlin/*/*/.travis.yml
|
||||
Marlin/*/*/*/.travis.yml
|
||||
Marlin/*/*/*/*/.travis.yml
|
||||
Marlin/.gitignore
|
||||
Marlin/*/.gitignore
|
||||
Marlin/*/*/.gitignore
|
||||
Marlin/*/*/*/.gitignore
|
||||
Marlin/*/*/*/*/.gitignore
|
||||
Marlin/readme.txt
|
||||
Marlin/*/readme.txt
|
||||
Marlin/*/*/readme.txt
|
||||
Marlin/*/*/*/readme.txt
|
||||
Marlin/*/*/*/*/readme.txt
|
||||
|
||||
# Secure Credentials
|
||||
Configuration_Secure.h
|
||||
|
||||
#Visual Studio
|
||||
# Visual Studio
|
||||
*.sln
|
||||
*.vcxproj
|
||||
*.vcxproj.user
|
||||
@@ -160,27 +122,49 @@ __vm/
|
||||
.vs/
|
||||
vc-fileutils.settings
|
||||
|
||||
#Visual Studio Code
|
||||
.vscode
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/*.db
|
||||
# Visual Studio Code
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
|
||||
#cmake
|
||||
# Simulation files
|
||||
imgui.ini
|
||||
eeprom.dat
|
||||
spi_flash.bin
|
||||
fs.img
|
||||
|
||||
# CMake
|
||||
buildroot/share/cmake/*
|
||||
CMakeLists.txt
|
||||
!buildroot/share/cmake/CMakeLists.txt
|
||||
src/CMakeLists.txt
|
||||
CMakeListsPrivate.txt
|
||||
build/
|
||||
|
||||
#CLion
|
||||
# CLion
|
||||
cmake-build-*
|
||||
|
||||
#Eclipse
|
||||
# Eclipse
|
||||
.project
|
||||
.cproject
|
||||
.pydevproject
|
||||
.settings
|
||||
.classpath
|
||||
|
||||
#Python
|
||||
# Python
|
||||
__pycache__
|
||||
|
||||
# IOLogger logs
|
||||
*_log.csv
|
||||
|
||||
# Misc.
|
||||
*~
|
||||
*.orig
|
||||
*.rej
|
||||
*.bak
|
||||
*.idea
|
||||
*.i
|
||||
*.ii
|
||||
*.swp
|
||||
tags
|
||||
*.logs
|
||||
*.bak
|
||||
|
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
@@ -431,6 +431,12 @@
|
||||
#define DUMMY_THERMISTOR_998_VALUE 25
|
||||
#define DUMMY_THERMISTOR_999_VALUE 100
|
||||
|
||||
// Resistor values when using a MAX31865 (sensor -5)
|
||||
// Sensor value is typically 100 (PT100) or 1000 (PT1000)
|
||||
// Calibration value is typically 430 ohm for AdaFruit PT100 modules and 4300 ohm for AdaFruit PT1000 modules.
|
||||
//#define MAX31865_SENSOR_OHMS 100
|
||||
//#define MAX31865_CALIBRATION_OHMS 430
|
||||
|
||||
// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings
|
||||
// from the two sensors differ too much the print will be aborted.
|
||||
//#define TEMP_SENSOR_1_AS_REDUNDANT
|
||||
@@ -2198,43 +2204,47 @@
|
||||
//=============================== Graphical TFTs ==============================
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// TFT display with optional touch screen
|
||||
// Color Marlin UI with standard menu system
|
||||
//
|
||||
//#define TFT_320x240
|
||||
//#define TFT_320x240_SPI
|
||||
//#define TFT_480x320
|
||||
//#define TFT_480x320_SPI
|
||||
/**
|
||||
* TFT Type - Select your Display type
|
||||
*
|
||||
* Available options are:
|
||||
* MKS_TS35_V2_0,
|
||||
* MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35,
|
||||
* MKS_ROBIN_TFT43, MKS_ROBIN_TFT_V1_1R
|
||||
* TFT_TRONXY_X5SA, ANYCUBIC_TFT35, LONGER_LK_TFT28
|
||||
* TFT_GENERIC
|
||||
*
|
||||
* For TFT_GENERIC, you need to configure these 3 options:
|
||||
* Driver: TFT_DRIVER
|
||||
* Current Drivers are: AUTO, ST7735, ST7789, ST7796, R61505, ILI9328, ILI9341, ILI9488
|
||||
* Resolution: TFT_WIDTH and TFT_HEIGHT
|
||||
* Interface: TFT_INTERFACE_FSMC or TFT_INTERFACE_SPI
|
||||
*/
|
||||
//#define TFT_GENERIC
|
||||
|
||||
//
|
||||
// Skip autodetect and force specific TFT driver
|
||||
// Mandatory for SPI screens with no MISO line
|
||||
// Available drivers are: ST7735, ST7789, ST7796, R61505, ILI9328, ILI9341, ILI9488
|
||||
//
|
||||
//#define TFT_DRIVER AUTO
|
||||
/**
|
||||
* TFT UI - User Interface Selection. Enable one of the following options:
|
||||
*
|
||||
* TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled
|
||||
* TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities
|
||||
* TFT_LVGL_UI - A Modern UI using LVGL
|
||||
*
|
||||
* For LVGL_UI also copy the 'assets' folder from the build directory to the
|
||||
* root of your SD card, together with the compiled firmware.
|
||||
*/
|
||||
//#define TFT_CLASSIC_UI
|
||||
//#define TFT_COLOR_UI
|
||||
//#define TFT_LVGL_UI
|
||||
|
||||
//
|
||||
// SPI display (MKS Robin Nano V2.0, MKS Gen L V2.0)
|
||||
// Upscaled 128x64 Marlin UI
|
||||
//
|
||||
//#define SPI_GRAPHICAL_TFT
|
||||
|
||||
//
|
||||
// FSMC display (MKS Robin, Alfawise U20, JGAurora A5S, REXYZ A1, etc.)
|
||||
// Upscaled 128x64 Marlin UI
|
||||
//
|
||||
//#define FSMC_GRAPHICAL_TFT
|
||||
|
||||
//
|
||||
// TFT LVGL UI
|
||||
//
|
||||
// Using default MKS icons and fonts from: https://git.io/JJvzK
|
||||
// Just copy the 'assets' folder from the build directory to the
|
||||
// root of your SD card, together with the compiled firmware.
|
||||
//
|
||||
//#define TFT_LVGL_UI_FSMC // Robin nano v1.2 uses FSMC
|
||||
//#define TFT_LVGL_UI_SPI // Robin nano v2.0 uses SPI
|
||||
/**
|
||||
* TFT Rotation. Set to one of the following values:
|
||||
*
|
||||
* TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y,
|
||||
* TFT_ROTATE_180, TFT_ROTATE_180_MIRROR_X, TFT_ROTATE_180_MIRROR_Y,
|
||||
* TFT_ROTATE_270, TFT_ROTATE_270_MIRROR_X, TFT_ROTATE_270_MIRROR_Y,
|
||||
* TFT_MIRROR_X, TFT_MIRROR_Y, TFT_NO_ROTATION
|
||||
*/
|
||||
//#define TFT_ROTATION TFT_NO_ROTATION
|
||||
|
||||
//=============================================================================
|
||||
//============================ Other Controllers ============================
|
||||
|
@@ -806,11 +806,9 @@
|
||||
#define TRAMMING_POINT_NAME_3 "Back-Right"
|
||||
#define TRAMMING_POINT_NAME_4 "Back-Left"
|
||||
|
||||
// Enable to restore leveling setup after operation
|
||||
#define RESTORE_LEVELING_AFTER_G35
|
||||
|
||||
// Add a menu item for Assisted Tramming
|
||||
//#define ASSISTED_TRAMMING_MENU_ITEM
|
||||
#define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation
|
||||
//#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first
|
||||
//#define ASSISTED_TRAMMING_MENU_ITEM // Add a menu item for Assisted Tramming
|
||||
|
||||
/**
|
||||
* Screw thread:
|
||||
@@ -1562,10 +1560,9 @@
|
||||
#endif
|
||||
|
||||
//
|
||||
// FSMC / SPI Graphical TFT
|
||||
// Classic UI Options
|
||||
//
|
||||
#if TFT_SCALED_DOGLCD
|
||||
//#define GRAPHICAL_TFT_ROTATE_180
|
||||
//#define TFT_MARLINUI_COLOR 0xFFFF // White
|
||||
//#define TFT_MARLINBG_COLOR 0x0000 // Black
|
||||
//#define TFT_DISABLED_COLOR 0x0003 // Almost black
|
||||
@@ -2141,7 +2138,7 @@
|
||||
* TMC26X Stepper Driver options
|
||||
*
|
||||
* The TMC26XStepper library is required for this stepper driver.
|
||||
* https://github.com/trinamic/TMC26XStepper
|
||||
* https://github.com/MarlinFirmware/TMC26XStepper
|
||||
*/
|
||||
#if HAS_DRIVER(TMC26X)
|
||||
|
||||
@@ -3378,6 +3375,25 @@
|
||||
//#define JOYSTICK_DEBUG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mechanical Gantry Calibration
|
||||
* Modern replacement for the Prusa TMC_Z_CALIBRATION.
|
||||
* Adds capability to work with any adjustable current drivers.
|
||||
* Implemented as G34 because M915 is deprecated.
|
||||
*/
|
||||
//#define MECHANICAL_GANTRY_CALIBRATION
|
||||
#if ENABLED(MECHANICAL_GANTRY_CALIBRATION)
|
||||
#define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma
|
||||
#define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move
|
||||
#define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move
|
||||
//#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction
|
||||
|
||||
//#define GANTRY_CALIBRATION_SAFE_POSITION { X_CENTER, Y_CENTER } // Safe position for nozzle
|
||||
//#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM
|
||||
//#define GANTRY_CALIBRATION_COMMANDS_PRE ""
|
||||
#define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MAX7219 Debug Matrix
|
||||
*
|
||||
|
@@ -28,7 +28,7 @@
|
||||
/**
|
||||
* Marlin release version identifier
|
||||
*/
|
||||
//#define SHORT_BUILD_VERSION "2.0.7.1"
|
||||
//#define SHORT_BUILD_VERSION "2.0.7.4"
|
||||
|
||||
/**
|
||||
* Verbose version identifier which should contain a reference to the location
|
||||
@@ -41,7 +41,7 @@
|
||||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
//#define STRING_DISTRIBUTION_DATE "2020-07-09"
|
||||
//#define STRING_DISTRIBUTION_DATE "2023-12-08"
|
||||
|
||||
/**
|
||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include "watchdog.h"
|
||||
#include "math.h"
|
||||
|
||||
#ifdef USBCON
|
||||
#ifdef IS_AT90USB
|
||||
#include <HardwareSerial.h>
|
||||
#else
|
||||
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
|
||||
@@ -81,7 +81,7 @@ typedef int8_t pin_t;
|
||||
//extern uint8_t MCUSR;
|
||||
|
||||
// Serial ports
|
||||
#ifdef USBCON
|
||||
#ifdef IS_AT90USB
|
||||
#define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial)
|
||||
#else
|
||||
#if !WITHIN(SERIAL_PORT, -1, 3)
|
||||
|
@@ -38,7 +38,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
|
||||
#if !IS_AT90USB && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
|
||||
|
||||
#include "MarlinSerial.h"
|
||||
#include "../../MarlinCore.h"
|
||||
@@ -792,10 +792,10 @@ MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
|
||||
#endif // !IS_AT90USB && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
|
||||
|
||||
// For AT90USB targets use the UART for BT interfacing
|
||||
#if defined(USBCON) && ENABLED(BLUETOOTH)
|
||||
#if BOTH(IS_AT90USB, BLUETOOTH)
|
||||
HardwareSerial bluetoothSerial;
|
||||
#endif
|
||||
|
||||
|
@@ -327,6 +327,6 @@
|
||||
#endif
|
||||
|
||||
// Use the UART for Bluetooth in AT90USB configurations
|
||||
#if defined(USBCON) && ENABLED(BLUETOOTH)
|
||||
#if BOTH(IS_AT90USB, BLUETOOTH)
|
||||
extern HardwareSerial bluetoothSerial;
|
||||
#endif
|
||||
|
@@ -154,7 +154,7 @@ void Stepper::digipot_init() {
|
||||
NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals)
|
||||
}
|
||||
|
||||
void Stepper::digipot_current(const uint8_t driver, const int16_t current) {
|
||||
void Stepper::set_digipot_current(const uint8_t driver, const int16_t current) {
|
||||
|
||||
if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed
|
||||
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
|
||||
|
||||
#ifndef I2C_ADDRESS
|
||||
#define I2C_ADDRESS(A) (A)
|
||||
#define I2C_ADDRESS(A) uint8_t(A)
|
||||
#endif
|
||||
|
||||
// Needed for AVR sprintf_P PROGMEM extension
|
||||
|
@@ -24,10 +24,3 @@
|
||||
#if HAS_FSMC_TFT
|
||||
#error "Sorry! FSMC TFT displays are not current available for HAL/LPC1768."
|
||||
#endif
|
||||
|
||||
// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
|
||||
#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
|
||||
#undef TOUCH_SCREEN
|
||||
#undef TOUCH_SCREEN_CALIBRATION
|
||||
#define HAS_TOUCH_XPT2046 1
|
||||
#endif
|
||||
|
@@ -191,7 +191,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
|
||||
//
|
||||
// Flag any i2c pin conflicts
|
||||
//
|
||||
#if ANY(HAS_I2C_DIGIPOT, DAC_STEPPER_CURRENT, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM)
|
||||
#if ANY(HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM)
|
||||
#define USEDI2CDEV_M 1 // <Arduino>/Wire.cpp
|
||||
|
||||
#if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1)
|
||||
|
@@ -36,7 +36,7 @@
|
||||
|
||||
#define DATASIZE_8BIT SSP_DATABIT_8
|
||||
#define DATASIZE_16BIT SSP_DATABIT_16
|
||||
#define TFT_IO TFT_SPI
|
||||
#define TFT_IO_DRIVER TFT_SPI
|
||||
|
||||
#define DMA_MINC_ENABLE 1
|
||||
#define DMA_MINC_DISABLE 0
|
||||
|
@@ -35,7 +35,8 @@
|
||||
|
||||
// MYSERIAL0 required before MarlinSerial includes!
|
||||
|
||||
#define _MSERIAL(X) Serial##X
|
||||
#define __MSERIAL(X) Serial##X
|
||||
#define _MSERIAL(X) __MSERIAL(X)
|
||||
#define MSERIAL(X) _MSERIAL(INCREMENT(X))
|
||||
|
||||
#if SERIAL_PORT == -1
|
||||
|
@@ -51,15 +51,15 @@ void FastIO_init(); // Must be called before using fast io macros
|
||||
|
||||
#if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32L0xx) || defined(STM32L4xx)
|
||||
#define _WRITE(IO, V) do { \
|
||||
if (V) FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO])) ; \
|
||||
else FastIOPortMap[STM_PORT(digitalPin[IO])]->BRR = _BV32(STM_PIN(digitalPin[IO])) ; \
|
||||
if (V) FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \
|
||||
else FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \
|
||||
}while(0)
|
||||
#else
|
||||
#define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO]) + ((V) ? 0 : 16)))
|
||||
#define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO)) + ((V) ? 0 : 16)))
|
||||
#endif
|
||||
|
||||
#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPin[IO])]->IDR, _BV32(STM_PIN(digitalPin[IO]))))
|
||||
#define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPin[IO])]->ODR ^= _BV32(STM_PIN(digitalPin[IO])))
|
||||
#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->IDR, _BV32(STM_PIN(digitalPinToPinName(IO)))))
|
||||
#define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR ^= _BV32(STM_PIN(digitalPinToPinName(IO))))
|
||||
|
||||
#define _GET_MODE(IO)
|
||||
#define _SET_MODE(IO,M) pinMode(IO, M)
|
||||
|
@@ -51,8 +51,8 @@
|
||||
* It contains:
|
||||
* - name of the signal
|
||||
* - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines.
|
||||
* EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as an
|
||||
* index into digitalPin[] to get the Port_pin number
|
||||
* EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as the
|
||||
* argument to digitalPinToPinName(IO) to get the Port_pin number
|
||||
* - if it is a digital or analog signal. PWMs are considered digital here.
|
||||
*
|
||||
* pin_xref is a structure generated by this header file. It is generated by the
|
||||
@@ -68,8 +68,6 @@
|
||||
* signal. The Arduino pin number is listed by the M43 I command.
|
||||
*/
|
||||
|
||||
extern const PinName digitalPin[]; // provided by the platform
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// make a list of the Arduino pin numbers in the Port/Pin order
|
||||
@@ -137,7 +135,7 @@ const XrefInfo pin_xref[] PROGMEM = {
|
||||
|
||||
uint8_t get_pin_mode(const pin_t Ard_num) {
|
||||
uint32_t mode_all = 0;
|
||||
const PinName dp = digitalPin[Ard_num];
|
||||
const PinName dp = digitalPinToPinName(Ard_num);
|
||||
switch (PORT_ALPHA(dp)) {
|
||||
case 'A' : mode_all = GPIOA->MODER; break;
|
||||
case 'B' : mode_all = GPIOB->MODER; break;
|
||||
@@ -218,7 +216,7 @@ bool pwm_status(const pin_t Ard_num) {
|
||||
void pwm_details(const pin_t Ard_num) {
|
||||
if (pwm_status(Ard_num)) {
|
||||
uint32_t alt_all = 0;
|
||||
const PinName dp = digitalPin[Ard_num];
|
||||
const PinName dp = digitalPinToPinName(Ard_num);
|
||||
pin_t pin_number = uint8_t(PIN_NUM(dp));
|
||||
const bool over_7 = pin_number >= 8;
|
||||
const uint8_t ind = over_7 ? 1 : 0;
|
||||
|
@@ -38,7 +38,7 @@
|
||||
|
||||
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
|
||||
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
|
||||
#define TFT_IO TFT_FSMC
|
||||
#define TFT_IO_DRIVER TFT_FSMC
|
||||
|
||||
#ifdef STM32F1xx
|
||||
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
|
||||
|
@@ -38,7 +38,7 @@
|
||||
|
||||
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
|
||||
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
|
||||
#define TFT_IO TFT_SPI
|
||||
#define TFT_IO_DRIVER TFT_SPI
|
||||
|
||||
class TFT_SPI {
|
||||
private:
|
||||
|
@@ -30,7 +30,11 @@
|
||||
#include "watchdog.h"
|
||||
#include <IWatchdog.h>
|
||||
|
||||
void watchdog_init() { IWatchdog.begin(4000000); } // 4 sec timeout
|
||||
void watchdog_init() {
|
||||
#if DISABLED(DISABLE_WATCHDOG_INIT)
|
||||
IWatchdog.begin(4000000); // 4 sec timeout
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_watchdog_refresh() {
|
||||
IWatchdog.reload();
|
||||
|
@@ -22,7 +22,6 @@
|
||||
|
||||
#if BOTH(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI)
|
||||
|
||||
#include "../HAL.h"
|
||||
#include <U8glib.h>
|
||||
|
||||
#undef SPI_SPEED
|
||||
@@ -161,5 +160,5 @@ uint8_t u8g_com_HAL_STM32F1_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB
|
||||
#endif // HAS_MARLINUI_U8GLIB && FORCE_SOFT_SPI
|
||||
#endif // STM32F1
|
||||
|
@@ -25,10 +25,3 @@
|
||||
//#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE."
|
||||
#undef SD_CHECK_AND_RETRY
|
||||
#endif
|
||||
|
||||
// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
|
||||
#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
|
||||
#undef TOUCH_SCREEN
|
||||
#undef TOUCH_SCREEN_CALIBRATION
|
||||
#define HAS_TOUCH_XPT2046 1
|
||||
#endif
|
||||
|
@@ -89,25 +89,12 @@ void TFT_FSMC::Init() {
|
||||
uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN;
|
||||
uint32_t controllerAddress;
|
||||
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT));
|
||||
#endif
|
||||
|
||||
#if ENABLED(LCD_USE_DMA_FSMC)
|
||||
dma_init(FSMC_DMA_DEV);
|
||||
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(TFT_RESET)
|
||||
OUT_WRITE(TFT_RESET_PIN, HIGH);
|
||||
delay(100);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
struct fsmc_nor_psram_reg_map* fsmcPsramRegion;
|
||||
|
||||
if (fsmcInit) return;
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
#define DATASIZE_8BIT DMA_SIZE_8BITS
|
||||
#define DATASIZE_16BIT DMA_SIZE_16BITS
|
||||
#define TFT_IO TFT_FSMC
|
||||
#define TFT_IO_DRIVER TFT_FSMC
|
||||
|
||||
typedef struct {
|
||||
__IO uint16_t REG;
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
#define DATASIZE_8BIT DATA_SIZE_8BIT
|
||||
#define DATASIZE_16BIT DATA_SIZE_16BIT
|
||||
#define TFT_IO TFT_SPI
|
||||
#define TFT_IO_DRIVER TFT_SPI
|
||||
|
||||
#define DMA_MINC_ENABLE 1
|
||||
#define DMA_MINC_DISABLE 0
|
||||
|
@@ -52,7 +52,9 @@ void watchdogSetup() {
|
||||
* @details The watchdog clock is 40Khz. We need a 4 seconds interval, so use a /256 preescaler and 625 reload value (counts down to 0)
|
||||
*/
|
||||
void watchdog_init() {
|
||||
//iwdg_init(IWDG_PRE_256, STM32F1_WD_RELOAD);
|
||||
#if DISABLED(DISABLE_WATCHDOG_INIT)
|
||||
iwdg_init(IWDG_PRE_256, STM32F1_WD_RELOAD);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
@@ -85,7 +85,7 @@
|
||||
#define START_FLASH_ADDR 0x08000000
|
||||
#define END_FLASH_ADDR 0x08100000
|
||||
|
||||
#elif MB(REMRAM_V1)
|
||||
#elif MB(REMRAM_V1, NUCLEO_F767ZI)
|
||||
|
||||
// For STM32F765VI in RemRam v1
|
||||
// SRAM (0x20000000 - 0x20080000) (512kb)
|
||||
|
@@ -97,7 +97,7 @@
|
||||
#include "feature/closedloop.h"
|
||||
#endif
|
||||
|
||||
#if HAS_I2C_DIGIPOT
|
||||
#if HAS_MOTOR_CURRENT_I2C
|
||||
#include "feature/digipot/digipot.h"
|
||||
#endif
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
#include "module/servo.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
#include "feature/dac/stepper_dac.h"
|
||||
#endif
|
||||
|
||||
@@ -1137,12 +1137,12 @@ void setup() {
|
||||
SETUP_RUN(enableStepperDrivers());
|
||||
#endif
|
||||
|
||||
#if HAS_I2C_DIGIPOT
|
||||
SETUP_RUN(digipot_i2c_init());
|
||||
#if HAS_MOTOR_CURRENT_I2C
|
||||
SETUP_RUN(digipot_i2c.init());
|
||||
#endif
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
SETUP_RUN(dac_init());
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
SETUP_RUN(stepper_dac.init());
|
||||
#endif
|
||||
|
||||
#if EITHER(Z_PROBE_SLED, SOLENOID_PROBE) && HAS_SOLENOID_1
|
||||
|
@@ -363,6 +363,7 @@
|
||||
#define BOARD_REMRAM_V1 5001 // RemRam v1
|
||||
#define BOARD_TEENSY41 5002 // Teensy 4.1
|
||||
#define BOARD_T41U5XBB 5003 // T41U5XBB Teensy 4.1 breakout board
|
||||
#define BOARD_NUCLEO_F767ZI 5004 // ST NUCLEO-F767ZI Dev Board
|
||||
|
||||
//
|
||||
// Espressif ESP32 WiFi
|
||||
|
@@ -452,6 +452,12 @@
|
||||
#define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)())
|
||||
#define _END_OF_ARGUMENTS_() 0
|
||||
|
||||
|
||||
// Simple Inline IF Macros, friendly to use in other macro definitions
|
||||
#define IF(O, A, B) ((O) ? (A) : (B))
|
||||
#define IF_0(O, A) IF(O, A, 0)
|
||||
#define IF_1(O, A) IF(O, A, 1)
|
||||
|
||||
//
|
||||
// REPEAT core macros. Recurse N times with ascending I.
|
||||
//
|
||||
|
@@ -1009,6 +1009,8 @@
|
||||
|
||||
lcd_mesh_edit_setup(new_z);
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
|
||||
do {
|
||||
idle();
|
||||
new_z = lcd_mesh_edit();
|
||||
@@ -1016,6 +1018,8 @@
|
||||
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
|
||||
} while (!ui.button_pressed());
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
|
||||
if (!lcd_map_control) ui.return_to_status(); // Just editing a single point? Return to status
|
||||
|
||||
if (click_and_hold(abort_fine_tune)) break; // Button held down? Abort editing
|
||||
|
@@ -32,16 +32,18 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
|
||||
#include "dac_mcp4728.h"
|
||||
|
||||
xyze_uint_t mcp4728_values;
|
||||
MCP4728 mcp4728;
|
||||
|
||||
xyze_uint_t dac_values;
|
||||
|
||||
/**
|
||||
* Begin I2C, get current values (input register and eeprom) of mcp4728
|
||||
*/
|
||||
void mcp4728_init() {
|
||||
void MCP4728::init() {
|
||||
Wire.begin();
|
||||
Wire.requestFrom(I2C_ADDRESS(DAC_DEV_ADDRESS), uint8_t(24));
|
||||
while (Wire.available()) {
|
||||
@@ -50,7 +52,7 @@ void mcp4728_init() {
|
||||
loByte = Wire.read();
|
||||
|
||||
if (!(deviceID & 0x08))
|
||||
mcp4728_values[(deviceID & 0x30) >> 4] = word((hiByte & 0x0F), loByte);
|
||||
dac_values[(deviceID & 0x30) >> 4] = word((hiByte & 0x0F), loByte);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,9 +60,9 @@ void mcp4728_init() {
|
||||
* Write input resister value to specified channel using fastwrite method.
|
||||
* Channel : 0-3, Values : 0-4095
|
||||
*/
|
||||
uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) {
|
||||
mcp4728_values[channel] = value;
|
||||
return mcp4728_fastWrite();
|
||||
uint8_t MCP4728::analogWrite(const uint8_t channel, const uint16_t value) {
|
||||
dac_values[channel] = value;
|
||||
return fastWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,12 +70,12 @@ uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) {
|
||||
* This will update both input register and EEPROM value
|
||||
* This will also write current Vref, PowerDown, Gain settings to EEPROM
|
||||
*/
|
||||
uint8_t mcp4728_eepromWrite() {
|
||||
uint8_t MCP4728::eepromWrite() {
|
||||
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
|
||||
Wire.write(SEQWRITE);
|
||||
LOOP_XYZE(i) {
|
||||
Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[i]));
|
||||
Wire.write(lowByte(mcp4728_values[i]));
|
||||
Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(dac_values[i]));
|
||||
Wire.write(lowByte(dac_values[i]));
|
||||
}
|
||||
return Wire.endTransmission();
|
||||
}
|
||||
@@ -81,7 +83,7 @@ uint8_t mcp4728_eepromWrite() {
|
||||
/**
|
||||
* Write Voltage reference setting to all input regiters
|
||||
*/
|
||||
uint8_t mcp4728_setVref_all(const uint8_t value) {
|
||||
uint8_t MCP4728::setVref_all(const uint8_t value) {
|
||||
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
|
||||
Wire.write(VREFWRITE | (value ? 0x0F : 0x00));
|
||||
return Wire.endTransmission();
|
||||
@@ -89,7 +91,7 @@ uint8_t mcp4728_setVref_all(const uint8_t value) {
|
||||
/**
|
||||
* Write Gain setting to all input regiters
|
||||
*/
|
||||
uint8_t mcp4728_setGain_all(const uint8_t value) {
|
||||
uint8_t MCP4728::setGain_all(const uint8_t value) {
|
||||
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
|
||||
Wire.write(GAINWRITE | (value ? 0x0F : 0x00));
|
||||
return Wire.endTransmission();
|
||||
@@ -98,16 +100,16 @@ uint8_t mcp4728_setGain_all(const uint8_t value) {
|
||||
/**
|
||||
* Return Input Register value
|
||||
*/
|
||||
uint16_t mcp4728_getValue(const uint8_t channel) { return mcp4728_values[channel]; }
|
||||
uint16_t MCP4728::getValue(const uint8_t channel) { return dac_values[channel]; }
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Steph: Might be useful in the future
|
||||
* Return Vout
|
||||
*/
|
||||
uint16_t mcp4728_getVout(const uint8_t channel) {
|
||||
uint16_t MCP4728::getVout(const uint8_t channel) {
|
||||
const uint32_t vref = 2048,
|
||||
vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096;
|
||||
vOut = (vref * dac_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096;
|
||||
return _MIN(vOut, defaultVDD);
|
||||
}
|
||||
#endif
|
||||
@@ -115,15 +117,15 @@ uint16_t mcp4728_getVout(const uint8_t channel) {
|
||||
/**
|
||||
* Returns DAC values as a 0-100 percentage of drive strength
|
||||
*/
|
||||
uint8_t mcp4728_getDrvPct(const uint8_t channel) { return uint8_t(100.0 * mcp4728_values[channel] / (DAC_STEPPER_MAX) + 0.5); }
|
||||
uint8_t MCP4728::getDrvPct(const uint8_t channel) { return uint8_t(100.0 * dac_values[channel] / (DAC_STEPPER_MAX) + 0.5); }
|
||||
|
||||
/**
|
||||
* Receives all Drive strengths as 0-100 percent values, updates
|
||||
* DAC Values array and calls fastwrite to update the DAC.
|
||||
*/
|
||||
void mcp4728_setDrvPct(xyze_uint8_t &pct) {
|
||||
mcp4728_values *= 0.01 * pct * (DAC_STEPPER_MAX);
|
||||
mcp4728_fastWrite();
|
||||
void MCP4728::setDrvPct(xyze_uint8_t &pct) {
|
||||
dac_values *= 0.01 * pct * (DAC_STEPPER_MAX);
|
||||
fastWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,11 +133,11 @@ void mcp4728_setDrvPct(xyze_uint8_t &pct) {
|
||||
* DAC Input and PowerDown bits update.
|
||||
* No EEPROM update
|
||||
*/
|
||||
uint8_t mcp4728_fastWrite() {
|
||||
uint8_t MCP4728::fastWrite() {
|
||||
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
|
||||
LOOP_XYZE(i) {
|
||||
Wire.write(highByte(mcp4728_values[i]));
|
||||
Wire.write(lowByte(mcp4728_values[i]));
|
||||
Wire.write(highByte(dac_values[i]));
|
||||
Wire.write(lowByte(dac_values[i]));
|
||||
}
|
||||
return Wire.endTransmission();
|
||||
}
|
||||
@@ -143,10 +145,10 @@ uint8_t mcp4728_fastWrite() {
|
||||
/**
|
||||
* Common function for simple general commands
|
||||
*/
|
||||
uint8_t mcp4728_simpleCommand(const byte simpleCommand) {
|
||||
uint8_t MCP4728::simpleCommand(const byte simpleCommand) {
|
||||
Wire.beginTransmission(I2C_ADDRESS(GENERALCALL));
|
||||
Wire.write(simpleCommand);
|
||||
return Wire.endTransmission();
|
||||
}
|
||||
|
||||
#endif // DAC_STEPPER_CURRENT
|
||||
#endif // HAS_MOTOR_CURRENT_DAC
|
||||
|
@@ -65,13 +65,18 @@
|
||||
// DAC_OR_ADDRESS defined in pins_BOARD.h file
|
||||
#define DAC_DEV_ADDRESS (BASE_ADDR | DAC_OR_ADDRESS)
|
||||
|
||||
void mcp4728_init();
|
||||
uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value);
|
||||
uint8_t mcp4728_eepromWrite();
|
||||
uint8_t mcp4728_setVref_all(const uint8_t value);
|
||||
uint8_t mcp4728_setGain_all(const uint8_t value);
|
||||
uint16_t mcp4728_getValue(const uint8_t channel);
|
||||
uint8_t mcp4728_fastWrite();
|
||||
uint8_t mcp4728_simpleCommand(const byte simpleCommand);
|
||||
uint8_t mcp4728_getDrvPct(const uint8_t channel);
|
||||
void mcp4728_setDrvPct(xyze_uint8_t &pct);
|
||||
class MCP4728 {
|
||||
public:
|
||||
static void init();
|
||||
static uint8_t analogWrite(const uint8_t channel, const uint16_t value);
|
||||
static uint8_t eepromWrite();
|
||||
static uint8_t setVref_all(const uint8_t value);
|
||||
static uint8_t setGain_all(const uint8_t value);
|
||||
static uint16_t getValue(const uint8_t channel);
|
||||
static uint8_t fastWrite();
|
||||
static uint8_t simpleCommand(const byte simpleCommand);
|
||||
static uint8_t getDrvPct(const uint8_t channel);
|
||||
static void setDrvPct(xyze_uint8_t &pct);
|
||||
};
|
||||
|
||||
extern MCP4728 mcp4728;
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
|
||||
#include "stepper_dac.h"
|
||||
#include "../../MarlinCore.h" // for SP_X_LBL...
|
||||
@@ -35,56 +35,53 @@ bool dac_present = false;
|
||||
constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER;
|
||||
xyze_uint8_t dac_channel_pct = DAC_MOTOR_CURRENT_DEFAULT;
|
||||
|
||||
int dac_init() {
|
||||
StepperDAC stepper_dac;
|
||||
|
||||
int StepperDAC::init() {
|
||||
#if PIN_EXISTS(DAC_DISABLE)
|
||||
OUT_WRITE(DAC_DISABLE_PIN, LOW); // set pin low to enable DAC
|
||||
#endif
|
||||
|
||||
mcp4728_init();
|
||||
mcp4728.init();
|
||||
|
||||
if (mcp4728_simpleCommand(RESET)) return -1;
|
||||
if (mcp4728.simpleCommand(RESET)) return -1;
|
||||
|
||||
dac_present = true;
|
||||
|
||||
mcp4728_setVref_all(DAC_STEPPER_VREF);
|
||||
mcp4728_setGain_all(DAC_STEPPER_GAIN);
|
||||
mcp4728.setVref_all(DAC_STEPPER_VREF);
|
||||
mcp4728.setGain_all(DAC_STEPPER_GAIN);
|
||||
|
||||
if (mcp4728_getDrvPct(0) < 1 || mcp4728_getDrvPct(1) < 1 || mcp4728_getDrvPct(2) < 1 || mcp4728_getDrvPct(3) < 1 ) {
|
||||
mcp4728_setDrvPct(dac_channel_pct);
|
||||
mcp4728_eepromWrite();
|
||||
if (mcp4728.getDrvPct(0) < 1 || mcp4728.getDrvPct(1) < 1 || mcp4728.getDrvPct(2) < 1 || mcp4728.getDrvPct(3) < 1 ) {
|
||||
mcp4728.setDrvPct(dac_channel_pct);
|
||||
mcp4728.eepromWrite();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dac_current_percent(uint8_t channel, float val) {
|
||||
if (!dac_present) return;
|
||||
|
||||
NOMORE(val, 100);
|
||||
|
||||
mcp4728_analogWrite(dac_order[channel], val * 0.01 * (DAC_STEPPER_MAX));
|
||||
mcp4728_simpleCommand(UPDATE);
|
||||
}
|
||||
|
||||
void dac_current_raw(uint8_t channel, uint16_t val) {
|
||||
void StepperDAC::set_current_value(const uint8_t channel, uint16_t val) {
|
||||
if (!dac_present) return;
|
||||
|
||||
NOMORE(val, uint16_t(DAC_STEPPER_MAX));
|
||||
|
||||
mcp4728_analogWrite(dac_order[channel], val);
|
||||
mcp4728_simpleCommand(UPDATE);
|
||||
mcp4728.analogWrite(dac_order[channel], val);
|
||||
mcp4728.simpleCommand(UPDATE);
|
||||
}
|
||||
|
||||
static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) * RECIPROCAL(DAC_STEPPER_MAX); }
|
||||
static float dac_amps(int8_t n) { return mcp4728_getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * RECIPROCAL(DAC_STEPPER_SENSE); }
|
||||
void StepperDAC::set_current_percent(const uint8_t channel, float val) {
|
||||
set_current_value(channel, _MIN(val, 100.0f) * (DAC_STEPPER_MAX) / 100.0f);
|
||||
}
|
||||
|
||||
uint8_t dac_current_get_percent(const AxisEnum axis) { return mcp4728_getDrvPct(dac_order[axis]); }
|
||||
void dac_current_set_percents(xyze_uint8_t &pct) {
|
||||
static float dac_perc(int8_t n) { return 100.0 * mcp4728.getValue(dac_order[n]) * RECIPROCAL(DAC_STEPPER_MAX); }
|
||||
static float dac_amps(int8_t n) { return mcp4728.getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * RECIPROCAL(DAC_STEPPER_SENSE); }
|
||||
|
||||
uint8_t StepperDAC::get_current_percent(const AxisEnum axis) { return mcp4728.getDrvPct(dac_order[axis]); }
|
||||
void StepperDAC::set_current_percents(xyze_uint8_t &pct) {
|
||||
LOOP_XYZE(i) dac_channel_pct[i] = pct[dac_order[i]];
|
||||
mcp4728_setDrvPct(dac_channel_pct);
|
||||
mcp4728.setDrvPct(dac_channel_pct);
|
||||
}
|
||||
|
||||
void dac_print_values() {
|
||||
void StepperDAC::print_values() {
|
||||
if (!dac_present) return;
|
||||
SERIAL_ECHO_MSG("Stepper current values in % (Amps):");
|
||||
SERIAL_ECHO_START();
|
||||
@@ -94,9 +91,9 @@ void dac_print_values() {
|
||||
SERIAL_ECHOLNPAIR_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")"));
|
||||
}
|
||||
|
||||
void dac_commit_eeprom() {
|
||||
void StepperDAC::commit_eeprom() {
|
||||
if (!dac_present) return;
|
||||
mcp4728_eepromWrite();
|
||||
mcp4728.eepromWrite();
|
||||
}
|
||||
|
||||
#endif // DAC_STEPPER_CURRENT
|
||||
#endif // HAS_MOTOR_CURRENT_DAC
|
||||
|
@@ -27,10 +27,15 @@
|
||||
|
||||
#include "dac_mcp4728.h"
|
||||
|
||||
int dac_init();
|
||||
void dac_current_percent(uint8_t channel, float val);
|
||||
void dac_current_raw(uint8_t channel, uint16_t val);
|
||||
void dac_print_values();
|
||||
void dac_commit_eeprom();
|
||||
uint8_t dac_current_get_percent(AxisEnum axis);
|
||||
void dac_current_set_percents(xyze_uint8_t &pct);
|
||||
class StepperDAC {
|
||||
public:
|
||||
static int init();
|
||||
static void set_current_percent(const uint8_t channel, float val);
|
||||
static void set_current_value(const uint8_t channel, uint16_t val);
|
||||
static void print_values();
|
||||
static void commit_eeprom();
|
||||
static uint8_t get_current_percent(AxisEnum axis);
|
||||
static void set_current_percents(xyze_uint8_t &pct);
|
||||
};
|
||||
|
||||
extern StepperDAC stepper_dac;
|
||||
|
@@ -21,5 +21,13 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
void digipot_i2c_set_current(const uint8_t channel, const float current);
|
||||
void digipot_i2c_init();
|
||||
//
|
||||
// Header for MCP4018 and MCP4451 current control i2c devices
|
||||
//
|
||||
class DigipotI2C {
|
||||
public:
|
||||
static void init();
|
||||
static void set_current(const uint8_t channel, const float current);
|
||||
};
|
||||
|
||||
DigipotI2C digipot_i2c;
|
||||
|
@@ -24,6 +24,8 @@
|
||||
|
||||
#if ENABLED(DIGIPOT_MCP4018)
|
||||
|
||||
#include "digipot.h"
|
||||
|
||||
#include <Stream.h>
|
||||
#include <SlowSoftI2CMaster.h> // https://github.com/stawel/SlowSoftI2CMaster
|
||||
|
||||
@@ -68,7 +70,7 @@ static SlowSoftI2CMaster pots[DIGIPOT_I2C_NUM_CHANNELS] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static void i2c_send(const uint8_t channel, const byte v) {
|
||||
static void digipot_i2c_send(const uint8_t channel, const byte v) {
|
||||
if (WITHIN(channel, 0, DIGIPOT_I2C_NUM_CHANNELS - 1)) {
|
||||
pots[channel].i2c_start(((DIGIPOT_I2C_ADDRESS_A) << 1) | I2C_WRITE);
|
||||
pots[channel].i2c_write(v);
|
||||
@@ -77,12 +79,12 @@ static void i2c_send(const uint8_t channel, const byte v) {
|
||||
}
|
||||
|
||||
// This is for the MCP4018 I2C based digipot
|
||||
void digipot_i2c_set_current(const uint8_t channel, const float current) {
|
||||
void DigipotI2C::set_current(const uint8_t channel, const float current) {
|
||||
const float ival = _MIN(_MAX(current, 0), float(DIGIPOT_MCP4018_MAX_VALUE));
|
||||
i2c_send(channel, current_to_wiper(ival));
|
||||
digipot_i2c_send(channel, current_to_wiper(ival));
|
||||
}
|
||||
|
||||
void digipot_i2c_init() {
|
||||
void DigipotI2C::init() {
|
||||
LOOP_L_N(i, DIGIPOT_I2C_NUM_CHANNELS) pots[i].i2c_init();
|
||||
|
||||
// Init currents according to Configuration_adv.h
|
||||
@@ -94,7 +96,7 @@ void digipot_i2c_init() {
|
||||
#endif
|
||||
;
|
||||
LOOP_L_N(i, COUNT(digipot_motor_current))
|
||||
digipot_i2c_set_current(i, pgm_read_float(&digipot_motor_current[i]));
|
||||
set_current(i, pgm_read_float(&digipot_motor_current[i]));
|
||||
}
|
||||
|
||||
#endif // DIGIPOT_MCP4018
|
||||
|
@@ -24,6 +24,8 @@
|
||||
|
||||
#if ENABLED(DIGIPOT_MCP4451)
|
||||
|
||||
#include "digipot.h"
|
||||
|
||||
#include <Stream.h>
|
||||
#include <Wire.h>
|
||||
|
||||
@@ -61,7 +63,7 @@ static void digipot_i2c_send(const byte addr, const byte a, const byte b) {
|
||||
}
|
||||
|
||||
// This is for the MCP4451 I2C based digipot
|
||||
void digipot_i2c_set_current(const uint8_t channel, const float current) {
|
||||
void DigipotI2C::set_current(const uint8_t channel, const float current) {
|
||||
// These addresses are specific to Azteeg X3 Pro, can be set to others.
|
||||
// In this case first digipot is at address A0=0, A1=0, second one is at A0=0, A1=1
|
||||
const byte addr = channel < 4 ? DIGIPOT_I2C_ADDRESS_A : DIGIPOT_I2C_ADDRESS_B; // channel 0-3 vs 4-7
|
||||
@@ -75,7 +77,7 @@ void digipot_i2c_set_current(const uint8_t channel, const float current) {
|
||||
digipot_i2c_send(addr, addresses[channel & 0x3], current_to_wiper(_MIN(float(_MAX(current, 0)), DIGIPOT_I2C_MAX_CURRENT)));
|
||||
}
|
||||
|
||||
void digipot_i2c_init() {
|
||||
void DigipotI2C::init() {
|
||||
#if MB(MKS_SBASE)
|
||||
configure_i2c(16); // Set clock_option to 16 ensure I2C is initialized at 400kHz
|
||||
#else
|
||||
@@ -90,7 +92,7 @@ void digipot_i2c_init() {
|
||||
#endif
|
||||
;
|
||||
LOOP_L_N(i, COUNT(digipot_motor_current))
|
||||
digipot_i2c_set_current(i, pgm_read_float(&digipot_motor_current[i]));
|
||||
set_current(i, pgm_read_float(&digipot_motor_current[i]));
|
||||
}
|
||||
|
||||
#endif // DIGIPOT_MCP4451
|
||||
|
@@ -61,6 +61,10 @@
|
||||
#include "../libs/buzzer.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
#include "powerloss.h"
|
||||
#endif
|
||||
|
||||
#include "../libs/nozzle.h"
|
||||
#include "pause.h"
|
||||
|
||||
@@ -640,6 +644,9 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
|
||||
// Set extruder to saved position
|
||||
planner.set_e_position_mm((destination.e = current_position.e = resume_position.e));
|
||||
|
||||
// Write PLR now to update the z axis value
|
||||
TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
|
||||
|
||||
TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS));
|
||||
|
||||
#ifdef ACTION_ON_RESUMED
|
||||
|
@@ -511,11 +511,9 @@ void GcodeSuite::G26() {
|
||||
g26_keep_heaters_on = parser.boolval('K');
|
||||
|
||||
// Accept 'I' if temperature presets are defined
|
||||
const uint8_t preset_index = (0
|
||||
#if PREHEAT_COUNT
|
||||
+ (parser.seenval('I') ? _MIN(parser.value_byte(), PREHEAT_COUNT - 1) + 1 : 0)
|
||||
#endif
|
||||
);
|
||||
#if PREHEAT_COUNT
|
||||
const uint8_t preset_index = parser.seenval('I') ? _MIN(parser.value_byte(), PREHEAT_COUNT - 1) + 1 : 0;
|
||||
#endif
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
|
||||
|
@@ -160,6 +160,7 @@ void GcodeSuite::G35() {
|
||||
" ", (screw_thread & 1) == (adjust > 0) ? "CCW" : "CW",
|
||||
" by ", abs(full_turns), " turns");
|
||||
if (minutes) SERIAL_ECHOPAIR(" and ", abs(minutes), " minutes");
|
||||
if (ENABLED(REPORT_TRAMMING_MM)) SERIAL_ECHOPAIR(" (", -diff, "mm)");
|
||||
SERIAL_EOL();
|
||||
}
|
||||
}
|
||||
|
@@ -201,10 +201,6 @@ G29_TYPE GcodeSuite::G29() {
|
||||
ABL_VAR int abl_probe_index;
|
||||
#endif
|
||||
|
||||
#if BOTH(HAS_SOFTWARE_ENDSTOPS, PROBE_MANUALLY)
|
||||
ABL_VAR bool saved_soft_endstops_state = true;
|
||||
#endif
|
||||
|
||||
#if ABL_GRID
|
||||
|
||||
#if ENABLED(PROBE_MANUALLY)
|
||||
@@ -461,7 +457,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
// Abort current G29 procedure, go back to idle state
|
||||
if (seenA && g29_in_progress) {
|
||||
SERIAL_ECHOLNPGM("Manual G29 aborted");
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = saved_soft_endstops_state);
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
set_bed_leveling_enabled(abl_should_enable);
|
||||
g29_in_progress = false;
|
||||
TERN_(LCD_BED_LEVELING, ui.wait_for_move = false);
|
||||
@@ -482,7 +478,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
|
||||
if (abl_probe_index == 0) {
|
||||
// For the initial G29 S2 save software endstop state
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, saved_soft_endstops_state = soft_endstops_enabled);
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
// Move close to the bed before the first point
|
||||
do_blocking_move_to_z(0);
|
||||
}
|
||||
@@ -552,14 +548,14 @@ G29_TYPE GcodeSuite::G29() {
|
||||
_manual_goto_xy(probePos); // Can be used here too!
|
||||
// Disable software endstops to allow manual adjustment
|
||||
// If G29 is not completed, they will not be re-enabled
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = false);
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
G29_RETURN(false);
|
||||
}
|
||||
else {
|
||||
// Leveling done! Fall through to G29 finishing code below
|
||||
SERIAL_ECHOLNPGM("Grid probing done.");
|
||||
// Re-enable software endstops, if needed
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = saved_soft_endstops_state);
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
}
|
||||
|
||||
#elif ENABLED(AUTO_BED_LEVELING_3POINT)
|
||||
@@ -570,7 +566,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
_manual_goto_xy(probePos);
|
||||
// Disable software endstops to allow manual adjustment
|
||||
// If G29 is not completed, they will not be re-enabled
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = false);
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
G29_RETURN(false);
|
||||
}
|
||||
else {
|
||||
@@ -578,7 +574,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
SERIAL_ECHOLNPGM("3-point probing done.");
|
||||
|
||||
// Re-enable software endstops, if needed
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = saved_soft_endstops_state);
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
|
||||
if (!dryrun) {
|
||||
vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal();
|
||||
|
@@ -61,7 +61,6 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM("
|
||||
void GcodeSuite::G29() {
|
||||
|
||||
static int mbl_probe_index = -1;
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, static bool saved_soft_endstops_state);
|
||||
|
||||
MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
|
||||
if (!WITHIN(state, 0, 5)) {
|
||||
@@ -98,26 +97,19 @@ void GcodeSuite::G29() {
|
||||
}
|
||||
// For each G29 S2...
|
||||
if (mbl_probe_index == 0) {
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
// For the initial G29 S2 save software endstop state
|
||||
saved_soft_endstops_state = soft_endstops_enabled;
|
||||
#endif
|
||||
// Move close to the bed before the first point
|
||||
do_blocking_move_to_z(0);
|
||||
}
|
||||
else {
|
||||
// Save Z for the previous mesh position
|
||||
mbl.set_zigzag_z(mbl_probe_index - 1, current_position.z);
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = saved_soft_endstops_state);
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
}
|
||||
// If there's another point to sample, move there with optional lift.
|
||||
if (mbl_probe_index < GRID_MAX_POINTS) {
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
// Disable software endstops to allow manual adjustment
|
||||
// If G29 is not completed, they will not be re-enabled
|
||||
soft_endstops_enabled = false;
|
||||
#endif
|
||||
|
||||
// Disable software endstops to allow manual adjustment
|
||||
// If G29 is left hanging without completion they won't be re-enabled!
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
mbl.zigzag(mbl_probe_index++, ix, iy);
|
||||
_manual_goto_xy({ mbl.index_to_xpos[ix], mbl.index_to_ypos[iy] });
|
||||
}
|
||||
|
@@ -222,8 +222,9 @@ void GcodeSuite::G28() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for planner moves to finish!
|
||||
planner.synchronize();
|
||||
planner.synchronize(); // Wait for planner moves to finish!
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state
|
||||
|
||||
// Disable the leveling matrix before homing
|
||||
#if HAS_LEVELING
|
||||
|
156
Marlin/src/gcode/calibrate/G34.cpp
Normal file
156
Marlin/src/gcode/calibrate/G34.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(MECHANICAL_GANTRY_CALIBRATION)
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/motion.h"
|
||||
#include "../../module/stepper.h"
|
||||
#include "../../module/endstops.h"
|
||||
|
||||
#if HAS_LEVELING
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
|
||||
#include "../../core/debug_out.h"
|
||||
|
||||
void GcodeSuite::G34() {
|
||||
|
||||
// Home before the alignment procedure
|
||||
if (!all_axes_known()) home_all_axes();
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
TEMPORARY_BED_LEVELING_STATE(false);
|
||||
TemporaryGlobalEndstopsState unlock_z(false);
|
||||
|
||||
#ifdef GANTRY_CALIBRATION_COMMANDS_PRE
|
||||
gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_PRE));
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Sub Commands Processed");
|
||||
#endif
|
||||
|
||||
#ifdef GANTRY_CALIBRATION_SAFE_POSITION
|
||||
// Move XY to safe position
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Parking XY");
|
||||
const xy_pos_t safe_pos = GANTRY_CALIBRATION_SAFE_POSITION;
|
||||
do_blocking_move_to(safe_pos, MMM_TO_MMS(GANTRY_CALIBRATION_XY_PARK_FEEDRATE));
|
||||
#endif
|
||||
|
||||
const float move_distance = parser.intval('Z', GANTRY_CALIBRATION_EXTRA_HEIGHT),
|
||||
zbase = ENABLED(GANTRY_CALIBRATION_TO_MIN) ? Z_MIN_POS : Z_MAX_POS,
|
||||
zpounce = zbase - move_distance, zgrind = zbase + move_distance;
|
||||
|
||||
// Move Z to pounce position
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Setting Z Pounce");
|
||||
do_blocking_move_to_z(zpounce, MMM_TO_MMS(HOMING_FEEDRATE_Z));
|
||||
|
||||
// Store current motor settings, then apply reduced value
|
||||
|
||||
#define _REDUCE_CURRENT ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_DAC, HAS_MOTOR_CURRENT_I2C, HAS_TRINAMIC_CONFIG)
|
||||
#if _REDUCE_CURRENT
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Reducing Current");
|
||||
#endif
|
||||
|
||||
#if HAS_MOTOR_CURRENT_SPI
|
||||
const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT);
|
||||
const uint32_t previous_current = stepper.motor_current_setting[Z_AXIS];
|
||||
stepper.set_digipot_current(Z_AXIS, target_current);
|
||||
#elif HAS_MOTOR_CURRENT_PWM
|
||||
const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT);
|
||||
const uint32_t previous_current = stepper.motor_current_setting[Z_AXIS];
|
||||
stepper.set_digipot_current(1, target_current);
|
||||
#elif HAS_MOTOR_CURRENT_DAC
|
||||
const float target_current = parser.floatval('S', GANTRY_CALIBRATION_CURRENT);
|
||||
const float previous_current = dac_amps(Z_AXIS, target_current);
|
||||
stepper_dac.set_current_value(Z_AXIS, target_current);
|
||||
#elif ENABLED(HAS_MOTOR_CURRENT_I2C)
|
||||
const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT);
|
||||
previous_current = dac_amps(Z_AXIS);
|
||||
digipot_i2c.set_current(Z_AXIS, target_current)
|
||||
#elif HAS_TRINAMIC_CONFIG
|
||||
const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT);
|
||||
static uint16_t previous_current_arr[NUM_Z_STEPPER_DRIVERS];
|
||||
#if AXIS_IS_TMC(Z)
|
||||
previous_current_arr[0] = stepperZ.getMilliamps();
|
||||
stepperZ.rms_current(target_current);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z2)
|
||||
previous_current_arr[1] = stepperZ2.getMilliamps();
|
||||
stepperZ2.rms_current(target_current);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z3)
|
||||
previous_current_arr[2] = stepperZ3.getMilliamps();
|
||||
stepperZ3.rms_current(target_current);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z4)
|
||||
previous_current_arr[3] = stepperZ4.getMilliamps();
|
||||
stepperZ4.rms_current(target_current);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Do Final Z move to adjust
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Final Z Move");
|
||||
do_blocking_move_to_z(zgrind, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE));
|
||||
|
||||
// Back off end plate, back to normal motion range
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Backoff");
|
||||
do_blocking_move_to_z(zpounce, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE));
|
||||
|
||||
#if _REDUCE_CURRENT
|
||||
// Reset current to original values
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore Current");
|
||||
#endif
|
||||
|
||||
#if HAS_MOTOR_CURRENT_SPI
|
||||
stepper.set_digipot_current(Z_AXIS, previous_current);
|
||||
#elif HAS_MOTOR_CURRENT_PWM
|
||||
stepper.set_digipot_current(1, previous_current);
|
||||
#elif HAS_MOTOR_CURRENT_DAC
|
||||
stepper_dac.set_current_value(Z_AXIS, previous_current);
|
||||
#elif ENABLED(HAS_MOTOR_CURRENT_I2C)
|
||||
digipot_i2c.set_current(Z_AXIS, previous_current)
|
||||
#elif HAS_TRINAMIC_CONFIG
|
||||
#if AXIS_IS_TMC(Z)
|
||||
stepperZ.rms_current(previous_current_arr[0]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z2)
|
||||
stepperZ2.rms_current(previous_current_arr[1]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z3)
|
||||
stepperZ3.rms_current(previous_current_arr[2]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z4)
|
||||
stepperZ4.rms_current(previous_current_arr[3]);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef GANTRY_CALIBRATION_COMMANDS_POST
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Running Post Commands");
|
||||
gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_POST));
|
||||
#endif
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
}
|
||||
|
||||
#endif // MECHANICAL_GANTRY_CALIBRATION
|
@@ -20,28 +20,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
|
||||
#include "../../feature/z_stepper_align.h"
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/planner.h"
|
||||
#include "../../module/stepper.h"
|
||||
#include "../../module/motion.h"
|
||||
#include "../../module/stepper.h"
|
||||
#include "../../module/planner.h"
|
||||
#include "../../module/probe.h"
|
||||
|
||||
#if HAS_MULTI_HOTEND
|
||||
#include "../../module/tool_change.h"
|
||||
#endif
|
||||
#include "../../lcd/ultralcd.h" // for LCD_MESSAGEPGM
|
||||
|
||||
#if HAS_LEVELING
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
#endif
|
||||
|
||||
#if HAS_MULTI_HOTEND
|
||||
#include "../../module/tool_change.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
||||
#include "../../libs/least_squares_fit.h"
|
||||
#include "../../libs/least_squares_fit.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
|
||||
@@ -117,7 +118,7 @@ void GcodeSuite::G34() {
|
||||
// In BLTOUCH HS mode, the probe travels in a deployed state.
|
||||
// Users of G34 might have a badly misaligned bed, so raise Z by the
|
||||
// length of the deployed pin (BLTOUCH stroke < 7mm)
|
||||
#define Z_BASIC_CLEARANCE Z_CLEARANCE_BETWEEN_PROBES + 7.0f * BOTH(BLTOUCH, BLTOUCH_HS_MODE)
|
||||
#define Z_BASIC_CLEARANCE (Z_CLEARANCE_BETWEEN_PROBES + 7.0f * BOTH(BLTOUCH, BLTOUCH_HS_MODE))
|
||||
|
||||
// Compute a worst-case clearance height to probe from. After the first
|
||||
// iteration this will be re-calculated based on the actual bed position
|
||||
@@ -154,21 +155,29 @@ void GcodeSuite::G34() {
|
||||
z_maxdiff = 0.0f,
|
||||
amplification = z_auto_align_amplification;
|
||||
|
||||
// These are needed after the for-loop
|
||||
uint8_t iteration;
|
||||
bool err_break = false;
|
||||
float z_measured_min;
|
||||
|
||||
#if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
||||
bool adjustment_reverse = false;
|
||||
#endif
|
||||
|
||||
// 'iteration' is declared above and is also used after the for-loop.
|
||||
// *not* the same as LOOP_L_N(iteration, z_auto_align_iterations)
|
||||
for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) {
|
||||
#if HAS_DISPLAY
|
||||
PGM_P const msg_iteration = GET_TEXT(MSG_ITERATION);
|
||||
const uint8_t iter_str_len = strlen_P(msg_iteration);
|
||||
#endif
|
||||
|
||||
// Final z and iteration values will be used after breaking the loop
|
||||
float z_measured_min;
|
||||
uint8_t iteration = 0;
|
||||
bool err_break = false; // To break out of nested loops
|
||||
while (iteration < z_auto_align_iterations) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions.");
|
||||
|
||||
SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1));
|
||||
const int iter = iteration + 1;
|
||||
SERIAL_ECHOLNPAIR("\nG34 Iteration: ", iter);
|
||||
#if HAS_DISPLAY
|
||||
char str[iter_str_len + 2 + 1];
|
||||
sprintf_P(str, msg_iteration, iter);
|
||||
ui.set_status(str);
|
||||
#endif
|
||||
|
||||
// Initialize minimum value
|
||||
z_measured_min = 100000.0f;
|
||||
@@ -190,7 +199,8 @@ void GcodeSuite::G34() {
|
||||
// current_position.z has been manually altered in the "dirty trick" above.
|
||||
const float z_probed_height = probe.probe_at_point(z_stepper_align.xy[iprobe], raise_after, 0, true, false);
|
||||
if (isnan(z_probed_height)) {
|
||||
SERIAL_ECHOLNPGM("Probing failed.");
|
||||
SERIAL_ECHOLNPGM("Probing failed");
|
||||
LCD_MESSAGEPGM(MSG_LCD_PROBING_FAILED);
|
||||
err_break = true;
|
||||
break;
|
||||
}
|
||||
@@ -249,8 +259,39 @@ void GcodeSuite::G34() {
|
||||
, " Z3-Z1=", ABS(z_measured[2] - z_measured[0])
|
||||
#endif
|
||||
);
|
||||
#if HAS_DISPLAY
|
||||
char fstr1[10];
|
||||
#if NUM_Z_STEPPER_DRIVERS == 2
|
||||
char msg[6 + (6 + 5) * 1 + 1];
|
||||
#else
|
||||
char msg[6 + (6 + 5) * 3 + 1], fstr2[10], fstr3[10];
|
||||
#endif
|
||||
sprintf_P(msg,
|
||||
PSTR("Diffs Z1-Z2=%s"
|
||||
#if NUM_Z_STEPPER_DRIVERS == 3
|
||||
" Z2-Z3=%s"
|
||||
" Z3-Z1=%s"
|
||||
#endif
|
||||
), dtostrf(ABS(z_measured[0] - z_measured[1]), 1, 3, fstr1)
|
||||
#if NUM_Z_STEPPER_DRIVERS == 3
|
||||
, dtostrf(ABS(z_measured[1] - z_measured[2]), 1, 3, fstr2)
|
||||
, dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3)
|
||||
#endif
|
||||
);
|
||||
ui.set_status(msg);
|
||||
#endif
|
||||
|
||||
auto decreasing_accuracy = [](const float &v1, const float &v2){
|
||||
if (v1 < v2 * 0.7f) {
|
||||
SERIAL_ECHOLNPGM("Decreasing Accuracy Detected.");
|
||||
LCD_MESSAGEPGM(MSG_DECREASING_ACCURACY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
||||
|
||||
// Check if the applied corrections go in the correct direction.
|
||||
// Calculate the sum of the absolute deviations from the mean of the probe measurements.
|
||||
// Compare to the last iteration to ensure it's getting better.
|
||||
@@ -266,11 +307,8 @@ void GcodeSuite::G34() {
|
||||
z_align_level_indicator += ABS(z_measured[zstepper] - z_measured_mean);
|
||||
|
||||
// If it's getting worse, stop and throw an error
|
||||
if (last_z_align_level_indicator < z_align_level_indicator * 0.7f) {
|
||||
SERIAL_ECHOLNPGM("Decreasing accuracy detected.");
|
||||
err_break = true;
|
||||
break;
|
||||
}
|
||||
err_break = decreasing_accuracy(last_z_align_level_indicator, z_align_level_indicator);
|
||||
if (err_break) break;
|
||||
|
||||
last_z_align_level_indicator = z_align_level_indicator;
|
||||
#endif
|
||||
@@ -290,8 +328,7 @@ void GcodeSuite::G34() {
|
||||
if (z_align_abs) amplification = (iteration == 1) ? _MIN(last_z_align_move[zstepper] / z_align_abs, 2.0f) : z_auto_align_amplification;
|
||||
|
||||
// Check for less accuracy compared to last move
|
||||
if (last_z_align_move[zstepper] < z_align_abs * 0.7f) {
|
||||
SERIAL_ECHOLNPGM("Decreasing accuracy detected.");
|
||||
if (decreasing_accuracy(last_z_align_move[zstepper], z_align_abs)) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " last_z_align_move = ", last_z_align_move[zstepper]);
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " z_align_abs = ", z_align_abs);
|
||||
adjustment_reverse = !adjustment_reverse;
|
||||
@@ -329,9 +366,14 @@ void GcodeSuite::G34() {
|
||||
|
||||
if (err_break) break;
|
||||
|
||||
if (success_break) { SERIAL_ECHOLNPGM("Target accuracy achieved."); break; }
|
||||
if (success_break) {
|
||||
SERIAL_ECHOLNPGM("Target accuracy achieved.");
|
||||
LCD_MESSAGEPGM(MSG_ACCURACY_ACHIEVED);
|
||||
break;
|
||||
}
|
||||
|
||||
} // for (iteration)
|
||||
iteration++;
|
||||
} // while (iteration < z_auto_align_iterations)
|
||||
|
||||
if (err_break)
|
||||
SERIAL_ECHOLNPGM("G34 aborted.");
|
||||
|
@@ -581,13 +581,12 @@ void GcodeSuite::G425() {
|
||||
GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_PRE));
|
||||
#endif
|
||||
|
||||
TEMPORARY_SOFT_ENDSTOP_STATE(false);
|
||||
TEMPORARY_BED_LEVELING_STATE(false);
|
||||
|
||||
if (homing_needed_error()) return;
|
||||
|
||||
measurements_t m;
|
||||
TEMPORARY_BED_LEVELING_STATE(false);
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
|
||||
measurements_t m;
|
||||
float uncertainty = parser.seenval('U') ? parser.value_float() : CALIBRATION_MEASUREMENT_UNCERTAIN;
|
||||
|
||||
if (parser.seen('B'))
|
||||
@@ -612,6 +611,8 @@ void GcodeSuite::G425() {
|
||||
else
|
||||
calibrate_all();
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
|
||||
#ifdef CALIBRATION_SCRIPT_POST
|
||||
GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_POST));
|
||||
#endif
|
||||
|
@@ -46,6 +46,10 @@
|
||||
#include "../../lcd/extui/ui_api.h"
|
||||
#endif
|
||||
|
||||
#if HAS_RESUME_CONTINUE
|
||||
#include "../../lcd/ultralcd.h"
|
||||
#endif
|
||||
|
||||
#ifndef GET_PIN_MAP_PIN_M43
|
||||
#define GET_PIN_MAP_PIN_M43(Q) GET_PIN_MAP_PIN(Q)
|
||||
#endif
|
||||
@@ -362,7 +366,10 @@ void GcodeSuite::M43() {
|
||||
}
|
||||
}
|
||||
|
||||
if (TERN0(HAS_RESUME_CONTINUE, !wait_for_user)) break;
|
||||
#if HAS_RESUME_CONTINUE
|
||||
ui.update();
|
||||
if (!wait_for_user) break;
|
||||
#endif
|
||||
|
||||
safe_delay(200);
|
||||
}
|
||||
|
@@ -55,7 +55,7 @@ void GcodeSuite::M111() {
|
||||
}
|
||||
else {
|
||||
SERIAL_ECHOPGM(STR_DEBUG_OFF);
|
||||
#if !defined(__AVR__) || !defined(USBCON)
|
||||
#if !IS_AT90USB
|
||||
#if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
|
||||
SERIAL_ECHOPAIR("\nBuffer Overruns: ", MYSERIAL0.buffer_overruns());
|
||||
#endif
|
||||
@@ -71,7 +71,7 @@ void GcodeSuite::M111() {
|
||||
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
|
||||
SERIAL_ECHOPAIR("\nMax RX Queue Size: ", MYSERIAL0.rxMaxEnqueued());
|
||||
#endif
|
||||
#endif // !defined(__AVR__) || !defined(USBCON)
|
||||
#endif // !IS_AT90USB
|
||||
}
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
@@ -37,8 +37,8 @@ void GcodeSuite::M211() {
|
||||
l_soft_max = soft_endstop.max.asLogical();
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPGM(STR_SOFT_ENDSTOPS);
|
||||
if (parser.seen('S')) soft_endstops_enabled = parser.value_bool();
|
||||
serialprint_onoff(soft_endstops_enabled);
|
||||
if (parser.seen('S')) soft_endstop._enabled = parser.value_bool();
|
||||
serialprint_onoff(soft_endstop._enabled);
|
||||
print_xyz(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" "));
|
||||
print_xyz(l_soft_max, PSTR(STR_SOFT_MAX));
|
||||
}
|
||||
|
@@ -70,9 +70,11 @@ void GcodeSuite::G12() {
|
||||
TEMPORARY_BED_LEVELING_STATE(!TEST(cleans, Z_AXIS) && planner.leveling_active);
|
||||
#endif
|
||||
|
||||
TEMPORARY_SOFT_ENDSTOP_STATE(parser.boolval('E'));
|
||||
SET_SOFT_ENDSTOP_LOOSE(!parser.boolval('E'));
|
||||
|
||||
nozzle.clean(pattern, strokes, radius, objects, cleans);
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
}
|
||||
|
||||
#endif // NOZZLE_CLEAN_FEATURE
|
||||
|
@@ -22,19 +22,19 @@
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if ANY(HAS_DIGIPOTSS, HAS_MOTOR_CURRENT_PWM, HAS_I2C_DIGIPOT, DAC_STEPPER_CURRENT)
|
||||
#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
|
||||
|
||||
#include "../../gcode.h"
|
||||
|
||||
#if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
|
||||
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
|
||||
#include "../../../module/stepper.h"
|
||||
#endif
|
||||
|
||||
#if HAS_I2C_DIGIPOT
|
||||
#if HAS_MOTOR_CURRENT_I2C
|
||||
#include "../../../feature/digipot/digipot.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
#include "../../../feature/dac/stepper_dac.h"
|
||||
#endif
|
||||
|
||||
@@ -42,61 +42,61 @@
|
||||
* M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S
|
||||
*/
|
||||
void GcodeSuite::M907() {
|
||||
#if HAS_DIGIPOTSS
|
||||
#if HAS_MOTOR_CURRENT_SPI
|
||||
|
||||
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.digipot_current(i, parser.value_int());
|
||||
if (parser.seenval('B')) stepper.digipot_current(4, parser.value_int());
|
||||
if (parser.seenval('S')) LOOP_LE_N(i, 4) stepper.digipot_current(i, parser.value_int());
|
||||
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.set_digipot_current(i, parser.value_int());
|
||||
if (parser.seenval('B')) stepper.set_digipot_current(4, parser.value_int());
|
||||
if (parser.seenval('S')) LOOP_LE_N(i, 4) stepper.set_digipot_current(i, parser.value_int());
|
||||
|
||||
#elif HAS_MOTOR_CURRENT_PWM
|
||||
|
||||
#if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY)
|
||||
if (parser.seenval('X') || parser.seenval('Y')) stepper.digipot_current(0, parser.value_int());
|
||||
if (parser.seenval('X') || parser.seenval('Y')) stepper.set_digipot_current(0, parser.value_int());
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
if (parser.seenval('Z')) stepper.digipot_current(1, parser.value_int());
|
||||
if (parser.seenval('Z')) stepper.set_digipot_current(1, parser.value_int());
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
if (parser.seenval('E')) stepper.digipot_current(2, parser.value_int());
|
||||
if (parser.seenval('E')) stepper.set_digipot_current(2, parser.value_int());
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if HAS_I2C_DIGIPOT
|
||||
#if HAS_MOTOR_CURRENT_I2C
|
||||
// this one uses actual amps in floating point
|
||||
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) digipot_i2c_set_current(i, parser.value_float());
|
||||
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) digipot_i2c.set_current(i, parser.value_float());
|
||||
// Additional extruders use B,C,D for channels 4,5,6.
|
||||
// TODO: Change these parameters because 'E' is used. B<index>?
|
||||
for (uint8_t i = E_AXIS + 1; i < DIGIPOT_I2C_NUM_CHANNELS; i++)
|
||||
if (parser.seenval('B' + i - (E_AXIS + 1))) digipot_i2c_set_current(i, parser.value_float());
|
||||
if (parser.seenval('B' + i - (E_AXIS + 1))) digipot_i2c.set_current(i, parser.value_float());
|
||||
#endif
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
if (parser.seenval('S')) {
|
||||
const float dac_percent = parser.value_float();
|
||||
LOOP_LE_N(i, 4) dac_current_percent(i, dac_percent);
|
||||
LOOP_LE_N(i, 4) stepper_dac.set_current_percent(i, dac_percent);
|
||||
}
|
||||
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) dac_current_percent(i, parser.value_float());
|
||||
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper_dac.set_current_percent(i, parser.value_float());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if EITHER(HAS_DIGIPOTSS, DAC_STEPPER_CURRENT)
|
||||
#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
|
||||
|
||||
/**
|
||||
* M908: Control digital trimpot directly (M908 P<pin> S<current>)
|
||||
*/
|
||||
void GcodeSuite::M908() {
|
||||
TERN_(HAS_DIGIPOTSS, stepper.digitalPotWrite(parser.intval('P'), parser.intval('S')));
|
||||
TERN_(DAC_STEPPER_CURRENT, dac_current_raw(parser.byteval('P', -1), parser.ushortval('S', 0)));
|
||||
TERN_(HAS_MOTOR_CURRENT_SPI, stepper.set_digipot_value_spi(parser.intval('P'), parser.intval('S')));
|
||||
TERN_(HAS_MOTOR_CURRENT_DAC, stepper_dac.set_current_value(parser.byteval('P', -1), parser.ushortval('S', 0)));
|
||||
}
|
||||
|
||||
#endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
void GcodeSuite::M909() { stepper_dac.print_values(); }
|
||||
void GcodeSuite::M910() { stepper_dac.commit_eeprom(); }
|
||||
|
||||
void GcodeSuite::M909() { dac_print_values(); }
|
||||
void GcodeSuite::M910() { dac_commit_eeprom(); }
|
||||
#endif // HAS_MOTOR_CURRENT_DAC
|
||||
|
||||
#endif // DAC_STEPPER_CURRENT
|
||||
#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_DAC
|
||||
|
||||
#endif // HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM || HAS_I2C_DIGIPOT || DAC_STEPPER_CURRENT
|
||||
#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC
|
||||
|
@@ -327,7 +327,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 33: G33(); break; // G33: Delta Auto-Calibration
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
#if EITHER(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION)
|
||||
case 34: G34(); break; // G34: Z Stepper automatic alignment using probe
|
||||
#endif
|
||||
|
||||
@@ -823,11 +823,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 900: M900(); break; // M900: Set advance K factor.
|
||||
#endif
|
||||
|
||||
#if ANY(HAS_DIGIPOTSS, HAS_MOTOR_CURRENT_PWM, HAS_I2C_DIGIPOT, DAC_STEPPER_CURRENT)
|
||||
#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
|
||||
case 907: M907(); break; // M907: Set digital trimpot motor current using axis codes.
|
||||
#if EITHER(HAS_DIGIPOTSS, DAC_STEPPER_CURRENT)
|
||||
#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
|
||||
case 908: M908(); break; // M908: Control digital trimpot directly.
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
case 909: M909(); break; // M909: Print digipot/DAC current value
|
||||
case 910: M910(); break; // M910: Commit digipot/DAC value to external EEPROM
|
||||
#endif
|
||||
|
@@ -258,9 +258,9 @@
|
||||
* M900 - Get or Set Linear Advance K-factor. (Requires LIN_ADVANCE)
|
||||
* M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470)
|
||||
* M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots)
|
||||
* M908 - Control digital trimpot directly. (Requires DAC_STEPPER_CURRENT or DIGIPOTSS_PIN)
|
||||
* M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT)
|
||||
* M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT)
|
||||
* M908 - Control digital trimpot directly. (Requires HAS_MOTOR_CURRENT_DAC or DIGIPOTSS_PIN)
|
||||
* M909 - Print digipot/DAC current value. (Requires HAS_MOTOR_CURRENT_DAC)
|
||||
* M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires HAS_MOTOR_CURRENT_DAC)
|
||||
* M911 - Report stepper driver overtemperature pre-warn condition. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660)
|
||||
* M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660)
|
||||
* M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD)
|
||||
@@ -465,11 +465,12 @@ private:
|
||||
|
||||
TERN_(DELTA_AUTO_CALIBRATION, static void G33());
|
||||
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
#if EITHER(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION)
|
||||
static void G34();
|
||||
static void M422();
|
||||
#endif
|
||||
|
||||
TERN_(Z_STEPPER_AUTO_ALIGN, static void M422());
|
||||
|
||||
TERN_(ASSISTED_TRAMMING, static void G35());
|
||||
|
||||
TERN_(G38_PROBE_TARGET, static void G38(const int8_t subcode));
|
||||
@@ -847,11 +848,11 @@ private:
|
||||
static void M918();
|
||||
#endif
|
||||
|
||||
#if ANY(HAS_DIGIPOTSS, HAS_MOTOR_CURRENT_PWM, HAS_I2C_DIGIPOT, DAC_STEPPER_CURRENT)
|
||||
#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
|
||||
static void M907();
|
||||
#if EITHER(HAS_DIGIPOTSS, DAC_STEPPER_CURRENT)
|
||||
#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
|
||||
static void M908();
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
static void M909();
|
||||
static void M910();
|
||||
#endif
|
||||
|
@@ -25,8 +25,10 @@
|
||||
|
||||
#include "gcode.h"
|
||||
#include "../module/settings.h"
|
||||
#include "../module/temperature.h"
|
||||
#include "../libs/hex_print.h"
|
||||
#include "../HAL/shared/eeprom_if.h"
|
||||
#include "../HAL/shared/Delay.h"
|
||||
|
||||
/**
|
||||
* Dn: G-code for development and testing
|
||||
@@ -84,40 +86,23 @@
|
||||
}
|
||||
} break;
|
||||
|
||||
case 3: { // D3 Read / Write EEPROM
|
||||
uint8_t *pointer = parser.hex_adr_val('A');
|
||||
uint16_t len = parser.ushortval('C', 1);
|
||||
uintptr_t addr = (uintptr_t)pointer;
|
||||
#ifndef MARLIN_EEPROM_SIZE
|
||||
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
|
||||
#endif
|
||||
NOMORE(addr, (size_t)(MARLIN_EEPROM_SIZE - 1));
|
||||
NOMORE(len, MARLIN_EEPROM_SIZE - addr);
|
||||
if (parser.seenval('X')) {
|
||||
uint16_t val = parser.hex_val('X');
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
persistentStore.access_start();
|
||||
while(len--) {
|
||||
int pos = 0;
|
||||
persistentStore.write_data(pos, (uint8_t *)&val, sizeof(val));
|
||||
}
|
||||
SERIAL_EOL();
|
||||
persistentStore.access_finish();
|
||||
#else
|
||||
SERIAL_ECHOLN("NO EEPROM");
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
case 3: { // D3 Read / Write EEPROM
|
||||
uint8_t *pointer = parser.hex_adr_val('A');
|
||||
uint16_t len = parser.ushortval('C', 1);
|
||||
uintptr_t addr = (uintptr_t)pointer;
|
||||
#ifndef MARLIN_EEPROM_SIZE
|
||||
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
while (len--) {
|
||||
// Read bytes from EEPROM
|
||||
NOMORE(addr, (size_t)(MARLIN_EEPROM_SIZE - 1));
|
||||
NOMORE(len, MARLIN_EEPROM_SIZE - addr);
|
||||
if (parser.seenval('X')) {
|
||||
uint16_t val = parser.hex_val('X');
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
persistentStore.access_start();
|
||||
uint8_t val;
|
||||
while(len--) {
|
||||
int pos = 0;
|
||||
if (!persistentStore.read_data(pos, (uint8_t *)&val, sizeof(val))) {
|
||||
print_hex_byte(val);
|
||||
}
|
||||
persistentStore.write_data(pos, (uint8_t *)&val, sizeof(val));
|
||||
}
|
||||
SERIAL_EOL();
|
||||
persistentStore.access_finish();
|
||||
@@ -125,9 +110,28 @@
|
||||
SERIAL_ECHOLN("NO EEPROM");
|
||||
#endif
|
||||
}
|
||||
SERIAL_EOL();
|
||||
}
|
||||
} break;
|
||||
else {
|
||||
while (len--) {
|
||||
// Read bytes from EEPROM
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
persistentStore.access_start();
|
||||
uint8_t val;
|
||||
while(len--) {
|
||||
int pos = 0;
|
||||
if (!persistentStore.read_data(pos, (uint8_t *)&val, sizeof(val))) {
|
||||
print_hex_byte(val);
|
||||
}
|
||||
}
|
||||
SERIAL_EOL();
|
||||
persistentStore.access_finish();
|
||||
#else
|
||||
SERIAL_ECHOLN("NO EEPROM");
|
||||
#endif
|
||||
}
|
||||
SERIAL_EOL();
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
|
||||
case 4: { // D4 Read / Write PIN
|
||||
// const uint8_t pin = parser.byteval('P');
|
||||
@@ -167,6 +171,20 @@
|
||||
SERIAL_EOL();
|
||||
}
|
||||
} break;
|
||||
|
||||
case 100: { // D100 Disable heaters and attempt a hard hang (Watchdog Test)
|
||||
SERIAL_ECHOLN("Disabling heaters and attempting to trigger Watchdog");
|
||||
SERIAL_ECHOLN("(USE_WATCHDOG " TERN(USE_WATCHDOG, "ENABLED", "DISABLED") ")");
|
||||
thermalManager.disable_all_heaters();
|
||||
delay(1000); // Allow time to print
|
||||
DISABLE_ISRS();
|
||||
// Use a low-level delay that does not rely on interrupts to function
|
||||
// Do not spin forever, to avoid thermal risks if heaters are enabled and
|
||||
// watchdog does not work.
|
||||
DELAY_US(10000000);
|
||||
ENABLE_ISRS();
|
||||
SERIAL_ECHOLN("FAILURE: Watchdog did not trigger board reset.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -127,7 +127,7 @@ void GcodeSuite::M290() {
|
||||
#else
|
||||
PSTR("Babystep Z")
|
||||
#endif
|
||||
, babystep.axis_total[BS_AXIS_IND(Z_AXIS)]
|
||||
, babystep.axis_total[BS_TOTAL_IND(Z_AXIS)]
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
@@ -624,7 +624,7 @@ void GCodeQueue::advance() {
|
||||
card.closefile();
|
||||
SERIAL_ECHOLNPGM(STR_FILE_SAVED);
|
||||
|
||||
#if !defined(__AVR__) || !defined(USBCON)
|
||||
#if !IS_AT90USB
|
||||
#if ENABLED(SERIAL_STATS_DROPPED_RX)
|
||||
SERIAL_ECHOLNPAIR("Dropped bytes: ", MYSERIAL0.dropped());
|
||||
#endif
|
||||
|
@@ -63,12 +63,12 @@
|
||||
#elif ENABLED(CARTESIO_UI)
|
||||
|
||||
#define DOGLCD
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#elif EITHER(DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE)
|
||||
|
||||
#define IS_DWIN_MARLINUI 1
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD)
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
#define IS_RRW_KEYPAD
|
||||
#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0
|
||||
#define ADC_KEY_NUM 8
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
// This helps to implement ADC_KEYPAD menus
|
||||
#define REVERSE_MENU_DIRECTION
|
||||
@@ -98,7 +98,7 @@
|
||||
#define IS_U8GLIB_SSD1306
|
||||
|
||||
#elif ENABLED(RADDS_DISPLAY)
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#define ENCODER_PULSES_PER_STEP 2
|
||||
|
||||
#elif EITHER(ANET_FULL_GRAPHICS_LCD, BQ_LCD_SMART_CONTROLLER)
|
||||
@@ -108,7 +108,7 @@
|
||||
#elif ANY(miniVIKI, VIKI2, ELB_FULL_GRAPHIC_CONTROLLER, AZSMZ_12864)
|
||||
|
||||
#define DOGLCD
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#if ENABLED(miniVIKI)
|
||||
#define U8GLIB_ST7565_64128N
|
||||
@@ -123,19 +123,19 @@
|
||||
#elif ENABLED(OLED_PANEL_TINYBOY2)
|
||||
|
||||
#define IS_U8GLIB_SSD1306
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#elif ENABLED(RA_CONTROL_PANEL)
|
||||
|
||||
#define LCD_I2C_TYPE_PCA8574
|
||||
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
|
||||
|
||||
#define DOGLCD
|
||||
#define U8GLIB_ST7920
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#elif ENABLED(CR10_STOCKDISPLAY)
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
|
||||
#define FYSETC_MINI_12864
|
||||
#define DOGLCD
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#define LED_COLORS_REDUCE_GREEN
|
||||
#if ENABLED(PSU_CONTROL) && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1)
|
||||
#define LED_BACKLIGHT_TIMEOUT 10000
|
||||
@@ -205,7 +205,7 @@
|
||||
|
||||
#elif ENABLED(ULTI_CONTROLLER)
|
||||
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#define U8GLIB_SSD1309
|
||||
#define LCD_RESET_PIN LCD_PINS_D6 // This controller need a reset pin
|
||||
#define ENCODER_PULSES_PER_STEP 2
|
||||
@@ -220,7 +220,7 @@
|
||||
#elif EITHER(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C)
|
||||
|
||||
#define IS_TFTGLCD_PANEL 1
|
||||
#define IS_ULTIPANEL // Note that IS_ULTIPANEL leads to HAS_WIRED_LCD
|
||||
#define IS_ULTIPANEL 1 // Note that IS_ULTIPANEL leads to HAS_WIRED_LCD
|
||||
|
||||
#if ENABLED(SDSUPPORT) && DISABLED(LCD_PROGRESS_BAR)
|
||||
#define LCD_PROGRESS_BAR
|
||||
@@ -246,7 +246,7 @@
|
||||
#endif
|
||||
|
||||
#if EITHER(MAKRPANEL, MINIPANEL)
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#define DOGLCD
|
||||
#if ENABLED(MAKRPANEL)
|
||||
#define U8GLIB_ST7565_64128N
|
||||
@@ -258,7 +258,7 @@
|
||||
#endif
|
||||
|
||||
#if ENABLED(OVERLORD_OLED)
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#define U8GLIB_SH1106
|
||||
/**
|
||||
* PCA9632 for buzzer and LEDs via i2c
|
||||
@@ -302,53 +302,64 @@
|
||||
|
||||
// Basic Ultipanel-like displays
|
||||
#if ANY(ULTIMAKERCONTROLLER, REPRAP_DISCOUNT_SMART_CONTROLLER, G3D_PANEL, RIGIDBOT_PANEL, PANEL_ONE, U8GLIB_SH1106)
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#endif
|
||||
|
||||
// Einstart OLED has Cardinal nav via pins defined in pins_EINSTART-S.h
|
||||
#if ENABLED(U8GLIB_SH1106_EINSTART)
|
||||
#define DOGLCD
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#endif
|
||||
|
||||
// Compatibility
|
||||
#if ENABLED(FSMC_GRAPHICAL_TFT)
|
||||
#define TFT_CLASSIC_UI
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define TFT_GENERIC
|
||||
#elif ENABLED(SPI_GRAPHICAL_TFT)
|
||||
#define TFT_CLASSIC_UI
|
||||
#define TFT_INTERFACE_SPI
|
||||
#define TFT_GENERIC
|
||||
#elif EITHER(TFT_320x240, TFT_480x320)
|
||||
#define TFT_COLOR_UI
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define TFT_GENERIC
|
||||
#elif EITHER(TFT_320x240_SPI, TFT_480x320_SPI)
|
||||
#define TFT_COLOR_UI
|
||||
#define TFT_INTERFACE_SPI
|
||||
#define TFT_GENERIC
|
||||
#elif ENABLED(TFT_LVGL_UI_FSMC)
|
||||
#define TFT_LVGL_UI
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define TFT_GENERIC
|
||||
#elif ENABLED(TFT_LVGL_UI_SPI)
|
||||
#define TFT_LVGL_UI
|
||||
#define TFT_INTERFACE_SPI
|
||||
#define TFT_GENERIC
|
||||
#endif
|
||||
|
||||
// FSMC/SPI TFT Panels (LVGL)
|
||||
#if EITHER(TFT_LVGL_UI_SPI, TFT_LVGL_UI_FSMC)
|
||||
#if ENABLED(TFT_LVGL_UI)
|
||||
#define HAS_TFT_LVGL_UI 1
|
||||
#endif
|
||||
|
||||
// FSMC/SPI TFT Panels
|
||||
#if EITHER(FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT)
|
||||
#if ENABLED(TFT_CLASSIC_UI)
|
||||
#define TFT_SCALED_DOGLCD 1
|
||||
#endif
|
||||
|
||||
#if TFT_SCALED_DOGLCD
|
||||
#define DOGLCD
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#define DELAYED_BACKLIGHT_INIT
|
||||
#elif ENABLED(TFT_LVGL_UI_SPI)
|
||||
#elif ENABLED(TFT_LVGL_UI)
|
||||
#define DELAYED_BACKLIGHT_INIT
|
||||
#endif
|
||||
|
||||
// FSMC/SPI TFT Panels using standard HAL/tft/tft_(fsmc|spi).h
|
||||
#if ANY(TFT_320x240, TFT_480x320, TFT_LVGL_UI_FSMC, FSMC_GRAPHICAL_TFT)
|
||||
#define HAS_FSMC_TFT 1
|
||||
#elif ANY(TFT_320x240_SPI, TFT_480x320_SPI, TFT_LVGL_UI_SPI, SPI_GRAPHICAL_TFT)
|
||||
#define HAS_SPI_TFT 1
|
||||
#endif
|
||||
|
||||
// Color UI
|
||||
#if ANY(TFT_320x240, TFT_480x320, TFT_320x240_SPI, TFT_480x320_SPI)
|
||||
#if ENABLED(TFT_COLOR_UI)
|
||||
#define HAS_GRAPHICAL_TFT 1
|
||||
#define IS_ULTIPANEL
|
||||
#endif
|
||||
|
||||
// Fewer lines with touch buttons on-screen
|
||||
#if EITHER(TFT_320x240, TFT_320x240_SPI)
|
||||
#define HAS_UI_320x240 1
|
||||
#define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7)
|
||||
#elif EITHER(TFT_480x320, TFT_480x320_SPI)
|
||||
#define HAS_UI_480x320 1
|
||||
#define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7)
|
||||
#define IS_ULTIPANEL 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -372,7 +383,7 @@
|
||||
#define LCD_I2C_TYPE_MCP23017
|
||||
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
|
||||
#define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (optional)
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#elif ENABLED(LCD_I2C_VIKI)
|
||||
|
||||
@@ -387,7 +398,7 @@
|
||||
#define LCD_I2C_TYPE_MCP23017
|
||||
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
|
||||
#define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
|
||||
#define ENCODER_FEEDRATE_DEADZONE 4
|
||||
|
||||
@@ -432,10 +443,10 @@
|
||||
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
|
||||
#if ENABLED(FF_INTERFACEBOARD)
|
||||
#define SR_LCD_3W_NL // Non latching 3 wire shift register
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#elif ENABLED(SAV_3DLCD)
|
||||
#define SR_LCD_2W_NL // Non latching 2 wire shift register
|
||||
#define IS_ULTIPANEL
|
||||
#define IS_ULTIPANEL 1
|
||||
#endif
|
||||
|
||||
#if ENABLED(IS_ULTIPANEL)
|
||||
@@ -810,3 +821,128 @@
|
||||
#ifndef EXTRUDE_MINTEMP
|
||||
#define EXTRUDE_MINTEMP 170
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TFT Displays
|
||||
*
|
||||
* Configure parameters for TFT displays:
|
||||
* - TFT_DEFAULT_ORIENTATION
|
||||
* - TFT_DRIVER
|
||||
* - TFT_WIDTH
|
||||
* - TFT_HEIGHT
|
||||
* - TFT_INTERFACE_(SPI|FSMC)
|
||||
* - TFT_COLOR
|
||||
* - GRAPHICAL_TFT_UPSCALE
|
||||
*/
|
||||
#if ENABLED(MKS_TS35_V2_0)
|
||||
// Most common: ST7796
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY)
|
||||
#define TFT_WIDTH 480
|
||||
#define TFT_HEIGHT 320
|
||||
#define TFT_INTERFACE_SPI
|
||||
#define GRAPHICAL_TFT_UPSCALE 3
|
||||
#elif ENABLED(MKS_ROBIN_TFT24)
|
||||
// Most common: ST7789
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_Y)
|
||||
#define TFT_WIDTH 320
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 2
|
||||
#elif ENABLED(MKS_ROBIN_TFT28)
|
||||
// Most common: ST7789
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_Y)
|
||||
#define TFT_WIDTH 320
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 2
|
||||
#elif ENABLED(MKS_ROBIN_TFT32)
|
||||
// Most common: ST7789
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_Y)
|
||||
#define TFT_WIDTH 320
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 2
|
||||
#elif ENABLED(MKS_ROBIN_TFT35)
|
||||
// Most common: ILI9488
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y)
|
||||
#define TFT_WIDTH 480
|
||||
#define TFT_HEIGHT 320
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 3
|
||||
#elif ENABLED(MKS_ROBIN_TFT43)
|
||||
#define TFT_DEFAULT_ORIENTATION 0
|
||||
#define TFT_DRIVER SSD1963
|
||||
#define TFT_WIDTH 480
|
||||
#define TFT_HEIGHT 272
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 2
|
||||
#elif ENABLED(MKS_ROBIN_TFT_V1_1R)
|
||||
// ILI9328 or R61505
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_INVERT_X | TFT_INVERT_Y | TFT_EXCHANGE_XY)
|
||||
#define TFT_WIDTH 320
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 2
|
||||
#elif EITHER(TFT_TRONXY_X5SA, ANYCUBIC_TFT35)
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y)
|
||||
#define TFT_DRIVER ILI9488
|
||||
#define TFT_WIDTH 480
|
||||
#define TFT_HEIGHT 320
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 3
|
||||
#elif ENABLED(LONGER_LK_TFT28)
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y)
|
||||
#define TFT_WIDTH 320
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_INTERFACE_FSMC
|
||||
#define GRAPHICAL_TFT_UPSCALE 2
|
||||
#elif ENABLED(TFT_GENERIC)
|
||||
#define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y)
|
||||
#endif
|
||||
|
||||
// FSMC/SPI TFT Panels using standard HAL/tft/tft_(fsmc|spi).h
|
||||
#if ENABLED(TFT_INTERFACE_FSMC)
|
||||
#define HAS_FSMC_TFT 1
|
||||
#if ENABLED(TFT_CLASSIC_UI)
|
||||
#define FSMC_GRAPHICAL_TFT
|
||||
#elif ENABLED(TFT_LVGL_UI)
|
||||
#define TFT_LVGL_UI_FSMC
|
||||
#endif
|
||||
#elif ENABLED(TFT_INTERFACE_SPI)
|
||||
#define HAS_SPI_TFT 1
|
||||
#if ENABLED(TFT_CLASSIC_UI)
|
||||
#define SPI_GRAPHICAL_TFT
|
||||
#elif ENABLED(TFT_LVGL_UI)
|
||||
#define TFT_LVGL_UI_SPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(TFT_COLOR_UI) && TFT_HEIGHT == 240
|
||||
#if ENABLED(TFT_INTERFACE_SPI)
|
||||
#define TFT_320x240_SPI
|
||||
#elif ENABLED(TFT_INTERFACE_FSMC)
|
||||
#define TFT_320x240
|
||||
#endif
|
||||
#elif ENABLED(TFT_COLOR_UI) && TFT_HEIGHT == 320
|
||||
#if ENABLED(TFT_INTERFACE_SPI)
|
||||
#define TFT_480x320_SPI
|
||||
#elif ENABLED(TFT_INTERFACE_FSMC)
|
||||
#define TFT_480x320
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Fewer lines with touch buttons on-screen
|
||||
#if EITHER(TFT_320x240, TFT_320x240_SPI)
|
||||
#define HAS_UI_320x240 1
|
||||
#define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7)
|
||||
#elif EITHER(TFT_480x320, TFT_480x320_SPI)
|
||||
#define HAS_UI_480x320 1
|
||||
#define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7)
|
||||
#endif
|
||||
|
||||
// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
|
||||
#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
|
||||
#undef TOUCH_SCREEN
|
||||
#undef TOUCH_SCREEN_CALIBRATION
|
||||
#define HAS_TOUCH_XPT2046 1
|
||||
#endif
|
||||
|
@@ -175,7 +175,7 @@
|
||||
#endif
|
||||
|
||||
#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
|
||||
#define HAS_I2C_DIGIPOT 1
|
||||
#define HAS_MOTOR_CURRENT_I2C 1
|
||||
#endif
|
||||
|
||||
// Multiple Z steppers
|
||||
@@ -208,7 +208,10 @@
|
||||
#define NEEDS_HARDWARE_PWM 1
|
||||
#endif
|
||||
|
||||
#if !defined(__AVR__) || !defined(USBCON)
|
||||
#if defined(__AVR__) && defined(USBCON)
|
||||
#define IS_AT90USB 1
|
||||
#undef SERIAL_XON_XOFF // Not supported on USB-native devices
|
||||
#else
|
||||
// Define constants and variables for buffering serial data.
|
||||
// Use only 0 or powers of 2 greater than 1
|
||||
// : [0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...]
|
||||
@@ -220,9 +223,6 @@
|
||||
#ifndef TX_BUFFER_SIZE
|
||||
#define TX_BUFFER_SIZE 32
|
||||
#endif
|
||||
#else
|
||||
// SERIAL_XON_XOFF not supported on USB-native devices
|
||||
#undef SERIAL_XON_XOFF
|
||||
#endif
|
||||
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
|
@@ -1976,7 +1976,7 @@
|
||||
#define HAS_STEPPER_RESET 1
|
||||
#endif
|
||||
#if PIN_EXISTS(DIGIPOTSS)
|
||||
#define HAS_DIGIPOTSS 1
|
||||
#define HAS_MOTOR_CURRENT_SPI 1
|
||||
#endif
|
||||
#if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_Z, MOTOR_CURRENT_PWM_E)
|
||||
#define HAS_MOTOR_CURRENT_PWM 1
|
||||
|
@@ -422,7 +422,7 @@
|
||||
#elif defined(CHAMBER_HEATER_PIN)
|
||||
#error "CHAMBER_HEATER_PIN is now HEATER_CHAMBER_PIN. Please update your configuration and/or pins."
|
||||
#elif defined(TMC_Z_CALIBRATION)
|
||||
#error "TMC_Z_CALIBRATION has been deprecated in favor of Z_STEPPER_AUTO_ALIGN. Please update your configuration."
|
||||
#error "TMC_Z_CALIBRATION has been deprecated in favor of MECHANICAL_GANTRY_CALIBRATION. Please update your configuration."
|
||||
#elif defined(Z_MIN_PROBE_ENDSTOP)
|
||||
#error "Z_MIN_PROBE_ENDSTOP is no longer required. Please remove it from Configuration.h."
|
||||
#elif defined(DUAL_NOZZLE_DUPLICATION_MODE)
|
||||
@@ -447,8 +447,6 @@
|
||||
#error "POWER_SUPPLY is now obsolete. Please remove it from Configuration.h."
|
||||
#elif defined(MKS_ROBIN_TFT)
|
||||
#error "MKS_ROBIN_TFT is now FSMC_GRAPHICAL_TFT. Please update your configuration."
|
||||
#elif defined(TFT_LVGL_UI)
|
||||
#error "TFT_LVGL_UI is now TFT_LVGL_UI_FSMC. Please update your configuration."
|
||||
#elif defined(SDPOWER)
|
||||
#error "SDPOWER is now SDPOWER_PIN. Please update your configuration and/or pins."
|
||||
#elif defined(STRING_SPLASH_LINE1) || defined(STRING_SPLASH_LINE2)
|
||||
@@ -535,6 +533,8 @@
|
||||
#error "ANYCUBIC_TFT_MODEL is now ANYCUBIC_LCD_I3MEGA. Please update your Configuration.h."
|
||||
#elif defined(EVENT_GCODE_SD_STOP)
|
||||
#error "EVENT_GCODE_SD_STOP is now EVENT_GCODE_SD_ABORT. Please update your Configuration.h."
|
||||
#elif defined(GRAPHICAL_TFT_ROTATE_180)
|
||||
#error "GRAPHICAL_TFT_ROTATE_180 is now TFT_ROTATION set to TFT_ROTATE_180. Please update your Configuration.h."
|
||||
#elif defined(FIL_RUNOUT_INVERTING)
|
||||
#if FIL_RUNOUT_INVERTING
|
||||
#error "FIL_RUNOUT_INVERTING true is now FIL_RUNOUT_STATE HIGH. Please update your Configuration.h."
|
||||
@@ -582,7 +582,7 @@
|
||||
/**
|
||||
* Serial
|
||||
*/
|
||||
#if !(defined(__AVR__) && defined(USBCON))
|
||||
#if !IS_AT90USB
|
||||
#if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024
|
||||
#error "SERIAL_XON_XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops."
|
||||
#elif RX_BUFFER_SIZE && (RX_BUFFER_SIZE < 2 || !IS_POWER_OF_2(RX_BUFFER_SIZE))
|
||||
@@ -1845,6 +1845,10 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
|
||||
#error "TEMP_SENSOR_1 is required with TEMP_SENSOR_1_AS_REDUNDANT."
|
||||
#endif
|
||||
|
||||
#if ENABLED(MAX6675_IS_MAX31865) && (!defined(MAX31865_SENSOR_OHMS) || !defined(MAX31865_CALIBRATION_OHMS))
|
||||
#error "MAX31865_SENSOR_OHMS and MAX31865_CALIBRATION_OHMS must be set in Configuration.h when using a MAX31865 temperature sensor."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Test Heater, Temp Sensor, and Extruder Pins
|
||||
*/
|
||||
@@ -2104,9 +2108,9 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
|
||||
#endif
|
||||
|
||||
/**
|
||||
* emergency-command parser
|
||||
* Emergency Command Parser
|
||||
*/
|
||||
#if ENABLED(EMERGENCY_PARSER) && defined(__AVR__) && defined(USBCON)
|
||||
#if BOTH(IS_AT90USB, EMERGENCY_PARSER)
|
||||
#error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)."
|
||||
#endif
|
||||
|
||||
@@ -2667,7 +2671,7 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
|
||||
/**
|
||||
* Digipot requirement
|
||||
*/
|
||||
#if HAS_I2C_DIGIPOT
|
||||
#if HAS_MOTOR_CURRENT_I2C
|
||||
#if BOTH(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
|
||||
#error "Enable only one of DIGIPOT_MCP4018 or DIGIPOT_MCP4451."
|
||||
#elif !MB(MKS_SBASE) \
|
||||
@@ -2788,6 +2792,25 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(MECHANICAL_GANTRY_CALIBRATION)
|
||||
#if NONE(HAS_MOTOR_CURRENT_DAC, HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC, HAS_TRINAMIC_CONFIG, HAS_MOTOR_CURRENT_PWM)
|
||||
#error "It is highly recommended to have adjustable current drivers to prevent damage. Disable this line to continue anyway."
|
||||
#elif !defined(GANTRY_CALIBRATION_CURRENT)
|
||||
#error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_CURRENT to be set."
|
||||
#elif !defined(GANTRY_CALIBRATION_EXTRA_HEIGHT)
|
||||
#error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_EXTRA_HEIGHT to be set."
|
||||
#elif !defined(GANTRY_CALIBRATION_FEEDRATE)
|
||||
#error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_FEEDRATE to be set."
|
||||
#endif
|
||||
#if defined(GANTRY_CALIBRATION_SAFE_POSITION) && !defined(GANTRY_CALIBRATION_XY_PARK_FEEDRATE)
|
||||
#error "GANTRY_CALIBRATION_SAFE_POSITION Requires GANTRY_CALIBRATION_XY_PARK_FEEDRATE to be set."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BOTH(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION)
|
||||
#error "You cannot use Z_STEPPER_AUTO_ALIGN and MECHANICAL_GANTRY_CALIBRATION at the same time."
|
||||
#endif
|
||||
|
||||
#if ENABLED(PRINTCOUNTER) && DISABLED(EEPROM_SETTINGS)
|
||||
#error "PRINTCOUNTER requires EEPROM_SETTINGS. Please update your Configuration."
|
||||
#endif
|
||||
|
@@ -25,7 +25,7 @@
|
||||
* Release version. Leave the Marlin version or apply a custom scheme.
|
||||
*/
|
||||
#ifndef SHORT_BUILD_VERSION
|
||||
#define SHORT_BUILD_VERSION "2.0.7.1"
|
||||
#define SHORT_BUILD_VERSION "2.0.7.4"
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@
|
||||
* version was tagged.
|
||||
*/
|
||||
#ifndef STRING_DISTRIBUTION_DATE
|
||||
#define STRING_DISTRIBUTION_DATE "2020-10-10"
|
||||
#define STRING_DISTRIBUTION_DATE "2023-12-08"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@@ -1341,7 +1341,7 @@
|
||||
#undef STATUS_LOGO_WIDTH
|
||||
#endif
|
||||
|
||||
#if (HAS_MULTI_HOTEND && STATUS_LOGO_WIDTH && BED_OR_CHAMBER_OR_FAN) || (HOTENDS >= 3 && !BED_OR_CHAMBER_OR_FAN)
|
||||
#if !defined(STATUS_HEATERS_X) && ((HAS_MULTI_HOTEND && STATUS_LOGO_WIDTH && BED_OR_CHAMBER_OR_FAN) || (HOTENDS >= 3 && !BED_OR_CHAMBER_OR_FAN))
|
||||
#define _STATUS_HEATERS_X(H,S,N) ((LCD_PIXEL_WIDTH - (H * (S + N)) - (_EXTRA_WIDTH) + (STATUS_LOGO_WIDTH)) / 2)
|
||||
#if STATUS_HOTEND1_WIDTH
|
||||
#if HOTENDS > 2
|
||||
|
@@ -66,12 +66,7 @@
|
||||
#define HAS_LCD_IO 1
|
||||
#endif
|
||||
|
||||
#if ENABLED(SPI_GRAPHICAL_TFT)
|
||||
#include HAL_PATH(../../HAL, tft/tft_spi.h)
|
||||
#elif ENABLED(FSMC_GRAPHICAL_TFT)
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
#endif
|
||||
|
||||
#include "../tft_io/tft_io.h"
|
||||
TFT_IO tftio;
|
||||
|
||||
#define WIDTH LCD_PIXEL_WIDTH
|
||||
@@ -132,299 +127,10 @@ TFT_IO tftio;
|
||||
#define TFT_BTOKMENU_COLOR COLOR_RED
|
||||
#endif
|
||||
|
||||
static uint32_t lcd_id = 0;
|
||||
|
||||
#define ST7789V_CASET 0x2A /* Column address register */
|
||||
#define ST7789V_RASET 0x2B /* Row address register */
|
||||
#define ST7789V_WRITE_RAM 0x2C /* Write data to GRAM */
|
||||
|
||||
|
||||
/* Mind the mess: with landscape screen orientation 'Horizontal' is Y and 'Vertical' is X */
|
||||
#define ILI9328_HASET 0x20 /* Horizontal GRAM address register (0-255) */
|
||||
#define ILI9328_VASET 0x21 /* Vertical GRAM address register (0-511)*/
|
||||
#define ILI9328_WRITE_RAM 0x22 /* Write data to GRAM */
|
||||
|
||||
#define ILI9328_HASTART 0x50 /* Horizontal address start position (0-255) */
|
||||
#define ILI9328_HAEND 0x51 /* Horizontal address end position (0-255) */
|
||||
#define ILI9328_VASTART 0x52 /* Vertical address start position (0-511) */
|
||||
#define ILI9328_VAEND 0x53 /* Vertical address end position (0-511) */
|
||||
|
||||
static void setWindow_ili9328(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
|
||||
#if HAS_LCD_IO
|
||||
tftio.DataTransferBegin(DATASIZE_8BIT);
|
||||
#define IO_REG_DATA(R,D) do { tftio.WriteReg(R); tftio.WriteData(D); }while(0)
|
||||
#else
|
||||
#define IO_REG_DATA(R,D) do { u8g_WriteByte(u8g, dev, R); u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&D); }while(0)
|
||||
#endif
|
||||
|
||||
#if NONE(LCD_USE_DMA_FSMC, LCD_USE_DMA_SPI)
|
||||
u8g_SetAddress(u8g, dev, 0);
|
||||
#endif
|
||||
|
||||
IO_REG_DATA(ILI9328_HASTART, Ymin);
|
||||
IO_REG_DATA(ILI9328_HAEND, Ymax);
|
||||
IO_REG_DATA(ILI9328_VASTART, Xmin);
|
||||
IO_REG_DATA(ILI9328_VAEND, Xmax);
|
||||
|
||||
IO_REG_DATA(ILI9328_HASET, Ymin);
|
||||
IO_REG_DATA(ILI9328_VASET, Xmin);
|
||||
|
||||
#if HAS_LCD_IO
|
||||
tftio.WriteReg(ILI9328_WRITE_RAM);
|
||||
tftio.DataTransferEnd();
|
||||
#else
|
||||
u8g_WriteByte(u8g, dev, ILI9328_WRITE_RAM);
|
||||
u8g_SetAddress(u8g, dev, 1);
|
||||
#endif
|
||||
static void setWindow(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
|
||||
tftio.set_window(Xmin, Ymin, Xmax, Ymax);
|
||||
}
|
||||
|
||||
static void setWindow_st7789v(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
|
||||
#if HAS_LCD_IO
|
||||
tftio.DataTransferBegin(DATASIZE_8BIT);
|
||||
tftio.WriteReg(ST7789V_CASET);
|
||||
tftio.WriteData((Xmin >> 8) & 0xFF);
|
||||
tftio.WriteData(Xmin & 0xFF);
|
||||
tftio.WriteData((Xmax >> 8) & 0xFF);
|
||||
tftio.WriteData(Xmax & 0xFF);
|
||||
|
||||
tftio.WriteReg(ST7789V_RASET);
|
||||
tftio.WriteData((Ymin >> 8) & 0xFF);
|
||||
tftio.WriteData(Ymin & 0xFF);
|
||||
tftio.WriteData((Ymax >> 8) & 0xFF);
|
||||
tftio.WriteData(Ymax & 0xFF);
|
||||
|
||||
tftio.WriteReg(ST7789V_WRITE_RAM);
|
||||
tftio.DataTransferEnd();
|
||||
#else
|
||||
u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_CASET); u8g_SetAddress(u8g, dev, 1);
|
||||
u8g_WriteByte(u8g, dev, (Xmin >> 8) & 0xFF);
|
||||
u8g_WriteByte(u8g, dev, Xmin & 0xFF);
|
||||
u8g_WriteByte(u8g, dev, (Xmax >> 8) & 0xFF);
|
||||
u8g_WriteByte(u8g, dev, Xmax & 0xFF);
|
||||
|
||||
u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_RASET); u8g_SetAddress(u8g, dev, 1);
|
||||
u8g_WriteByte(u8g, dev, (Ymin >> 8) & 0xFF);
|
||||
u8g_WriteByte(u8g, dev, Ymin & 0xFF);
|
||||
u8g_WriteByte(u8g, dev, (Ymax >> 8) & 0xFF);
|
||||
u8g_WriteByte(u8g, dev, Ymax & 0xFF);
|
||||
|
||||
u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_WRITE_RAM); u8g_SetAddress(u8g, dev, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void setWindow_none(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {}
|
||||
void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) = setWindow_none;
|
||||
|
||||
#define ESC_REG(x) 0xFFFF, 0x00FF & (uint16_t)x
|
||||
#define ESC_DELAY(x) 0xFFFF, 0x8000 | (x & 0x7FFF)
|
||||
#define ESC_END 0xFFFF, 0x7FFF
|
||||
#define ESC_FFFF 0xFFFF, 0xFFFF
|
||||
|
||||
#if HAS_LCD_IO
|
||||
void writeEscSequence(const uint16_t *sequence) {
|
||||
uint16_t data;
|
||||
for (;;) {
|
||||
data = *sequence++;
|
||||
if (data != 0xFFFF) {
|
||||
tftio.WriteData(data);
|
||||
continue;
|
||||
}
|
||||
data = *sequence++;
|
||||
if (data == 0x7FFF) return;
|
||||
if (data == 0xFFFF) {
|
||||
tftio.WriteData(data);
|
||||
} else if (data & 0x8000) {
|
||||
delay(data & 0x7FFF);
|
||||
} else if ((data & 0xFF00) == 0) {
|
||||
tftio.WriteReg(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
#define WRITE_ESC_SEQUENCE(V) writeEscSequence(V)
|
||||
#define WRITE_ESC_SEQUENCE16(V) writeEscSequence(V)
|
||||
#else
|
||||
void writeEscSequence8(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
|
||||
uint16_t data;
|
||||
u8g_SetAddress(u8g, dev, 1);
|
||||
for (;;) {
|
||||
data = *sequence++;
|
||||
if (data != 0xFFFF) {
|
||||
u8g_WriteByte(u8g, dev, data & 0xFF);
|
||||
continue;
|
||||
}
|
||||
data = *sequence++;
|
||||
if (data == 0x7FFF) return;
|
||||
if (data == 0xFFFF) {
|
||||
u8g_WriteByte(u8g, dev, data & 0xFF);
|
||||
} else if (data & 0x8000) {
|
||||
delay(data & 0x7FFF);
|
||||
} else if ((data & 0xFF00) == 0) {
|
||||
u8g_SetAddress(u8g, dev, 0);
|
||||
u8g_WriteByte(u8g, dev, data & 0xFF);
|
||||
u8g_SetAddress(u8g, dev, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE_ESC_SEQUENCE(V) writeEscSequence8(u8g, dev, V)
|
||||
|
||||
void writeEscSequence16(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
|
||||
uint16_t data;
|
||||
u8g_SetAddress(u8g, dev, 0);
|
||||
for (;;) {
|
||||
data = *sequence++;
|
||||
if (data != 0xFFFF) {
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data);
|
||||
continue;
|
||||
}
|
||||
data = *sequence++;
|
||||
if (data == 0x7FFF) return;
|
||||
if (data == 0xFFFF) {
|
||||
u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data);
|
||||
} else if (data & 0x8000) {
|
||||
delay(data & 0x7FFF);
|
||||
} else if ((data & 0xFF00) == 0) {
|
||||
u8g_WriteByte(u8g, dev, data & 0xFF);
|
||||
}
|
||||
}
|
||||
u8g_SetAddress(u8g, dev, 1);
|
||||
}
|
||||
|
||||
#define WRITE_ESC_SEQUENCE16(V) writeEscSequence16(u8g, dev, V)
|
||||
#endif
|
||||
|
||||
static const uint16_t st7789v_init[] = {
|
||||
ESC_REG(0x0010), ESC_DELAY(10),
|
||||
ESC_REG(0x0001), ESC_DELAY(200),
|
||||
ESC_REG(0x0011), ESC_DELAY(120),
|
||||
ESC_REG(0x0036), TERN(GRAPHICAL_TFT_ROTATE_180, 0x0060, 0x00A0),
|
||||
ESC_REG(0x003A), 0x0055,
|
||||
ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F,
|
||||
ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF,
|
||||
ESC_REG(0x00B2), 0x000C, 0x000C, 0x0000, 0x0033, 0x0033,
|
||||
ESC_REG(0x00B7), 0x0035,
|
||||
ESC_REG(0x00BB), 0x001F,
|
||||
ESC_REG(0x00C0), 0x002C,
|
||||
ESC_REG(0x00C2), 0x0001, 0x00C3,
|
||||
ESC_REG(0x00C4), 0x0020,
|
||||
ESC_REG(0x00C6), 0x000F,
|
||||
ESC_REG(0x00D0), 0x00A4, 0x00A1,
|
||||
ESC_REG(0x0029),
|
||||
ESC_REG(0x0011),
|
||||
ESC_END
|
||||
};
|
||||
|
||||
static const uint16_t ili9328_init[] = {
|
||||
ESC_REG(0x0001), 0x0100,
|
||||
ESC_REG(0x0002), 0x0400,
|
||||
ESC_REG(0x0003), 0x1038,
|
||||
ESC_REG(0x0004), 0x0000,
|
||||
ESC_REG(0x0008), 0x0202,
|
||||
ESC_REG(0x0009), 0x0000,
|
||||
ESC_REG(0x000A), 0x0000,
|
||||
ESC_REG(0x000C), 0x0000,
|
||||
ESC_REG(0x000D), 0x0000,
|
||||
ESC_REG(0x000F), 0x0000,
|
||||
ESC_REG(0x0010), 0x0000,
|
||||
ESC_REG(0x0011), 0x0007,
|
||||
ESC_REG(0x0012), 0x0000,
|
||||
ESC_REG(0x0013), 0x0000,
|
||||
ESC_REG(0x0007), 0x0001,
|
||||
ESC_DELAY(200),
|
||||
ESC_REG(0x0010), 0x1690,
|
||||
ESC_REG(0x0011), 0x0227,
|
||||
ESC_DELAY(50),
|
||||
ESC_REG(0x0012), 0x008C,
|
||||
ESC_DELAY(50),
|
||||
ESC_REG(0x0013), 0x1500,
|
||||
ESC_REG(0x0029), 0x0004,
|
||||
ESC_REG(0x002B), 0x000D,
|
||||
ESC_DELAY(50),
|
||||
ESC_REG(0x0050), 0x0000,
|
||||
ESC_REG(0x0051), 0x00EF,
|
||||
ESC_REG(0x0052), 0x0000,
|
||||
ESC_REG(0x0053), 0x013F,
|
||||
ESC_REG(0x0020), 0x0000,
|
||||
ESC_REG(0x0021), 0x0000,
|
||||
ESC_REG(0x0060), 0x2700,
|
||||
ESC_REG(0x0061), 0x0001,
|
||||
ESC_REG(0x006A), 0x0000,
|
||||
ESC_REG(0x0080), 0x0000,
|
||||
ESC_REG(0x0081), 0x0000,
|
||||
ESC_REG(0x0082), 0x0000,
|
||||
ESC_REG(0x0083), 0x0000,
|
||||
ESC_REG(0x0084), 0x0000,
|
||||
ESC_REG(0x0085), 0x0000,
|
||||
ESC_REG(0x0090), 0x0010,
|
||||
ESC_REG(0x0092), 0x0600,
|
||||
ESC_REG(0x0007), 0x0133,
|
||||
ESC_REG(0x0022),
|
||||
ESC_END
|
||||
};
|
||||
|
||||
static const uint16_t ili9341_init[] = {
|
||||
ESC_REG(0x0010), ESC_DELAY(10),
|
||||
ESC_REG(0x0001), ESC_DELAY(200),
|
||||
ESC_REG(0x0036), TERN(GRAPHICAL_TFT_ROTATE_180, 0x0028, 0x00E8),
|
||||
ESC_REG(0x003A), 0x0055,
|
||||
ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F,
|
||||
ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF,
|
||||
ESC_REG(0x00C5), 0x003E, 0x0028,
|
||||
ESC_REG(0x00C7), 0x0086,
|
||||
ESC_REG(0x00B1), 0x0000, 0x0018,
|
||||
ESC_REG(0x00C0), 0x0023,
|
||||
ESC_REG(0x00C1), 0x0010,
|
||||
ESC_REG(0x0029),
|
||||
ESC_REG(0x0011),
|
||||
ESC_DELAY(100),
|
||||
ESC_END
|
||||
};
|
||||
|
||||
static const uint16_t ili9488_init[] = {
|
||||
ESC_REG(0x00E0), 0x0000, 0x0007, 0x000F, 0x000D, 0x001B, 0x000A, 0x003C, 0x0078, 0x004A, 0x0007, 0x000E, 0x0009, 0x001B, 0x001E, 0x000F,
|
||||
ESC_REG(0x00E1), 0x0000, 0x0022, 0x0024, 0x0006, 0x0012, 0x0007, 0x0036, 0x0047, 0x0047, 0x0006, 0x000A, 0x0007, 0x0030, 0x0037, 0x000F,
|
||||
ESC_REG(0x00C0), 0x0010, 0x0010,
|
||||
ESC_REG(0x00C1), 0x0041,
|
||||
ESC_REG(0x00C5), 0x0000, 0x0022, 0x0080,
|
||||
ESC_REG(0x0036), TERN(GRAPHICAL_TFT_ROTATE_180, 0x00A8, 0x0068),
|
||||
ESC_REG(0x003A), 0x0055,
|
||||
ESC_REG(0x00B0), 0x0000,
|
||||
ESC_REG(0x00B1), 0x00B0, 0x0011,
|
||||
ESC_REG(0x00B4), 0x0002,
|
||||
ESC_REG(0x00B6), 0x0002, 0x0042,
|
||||
ESC_REG(0x00B7), 0x00C6,
|
||||
ESC_REG(0x00E9), 0x0000,
|
||||
ESC_REG(0x00F0), 0x00A9, 0x0051, 0x002C, 0x0082,
|
||||
ESC_REG(0x0029),
|
||||
ESC_REG(0x0011),
|
||||
ESC_DELAY(100),
|
||||
ESC_END
|
||||
};
|
||||
|
||||
static const uint16_t st7796_init[] = {
|
||||
ESC_REG(0x0010), ESC_DELAY(120),
|
||||
ESC_REG(0x0001), ESC_DELAY(120),
|
||||
ESC_REG(0x0011), ESC_DELAY(120),
|
||||
ESC_REG(0x00F0), 0x00C3,
|
||||
ESC_REG(0x00F0), 0x0096,
|
||||
ESC_REG(0x0036), TERN(GRAPHICAL_TFT_ROTATE_180, 0x00E8, 0x0028),
|
||||
ESC_REG(0x003A), 0x0055,
|
||||
ESC_REG(0x00B4), 0x0001,
|
||||
ESC_REG(0x00B7), 0x00C6,
|
||||
ESC_REG(0x00E8), 0x0040, 0x008A, 0x0000, 0x0000, 0x0029, 0x0019, 0x00A5, 0x0033,
|
||||
ESC_REG(0x00C1), 0x0006,
|
||||
ESC_REG(0x00C2), 0x00A7,
|
||||
ESC_REG(0x00C5), 0x0018,
|
||||
ESC_REG(0x00E0), 0x00F0, 0x0009, 0x000B, 0x0006, 0x0004, 0x0015, 0x002F, 0x0054, 0x0042, 0x003C, 0x0017, 0x0014, 0x0018, 0x001B,
|
||||
ESC_REG(0x00E1), 0x00F0, 0x0009, 0x000B, 0x0006, 0x0004, 0x0003, 0x002D, 0x0043, 0x0042, 0x003B, 0x0016, 0x0014, 0x0017, 0x001B,
|
||||
ESC_REG(0x00F0), 0x003C,
|
||||
ESC_REG(0x00F0), 0x0069, ESC_DELAY(120),
|
||||
ESC_REG(0x0029),
|
||||
ESC_REG(0x0011),
|
||||
ESC_DELAY(100),
|
||||
ESC_END
|
||||
};
|
||||
|
||||
#if HAS_TOUCH_XPT2046
|
||||
|
||||
static const uint8_t buttonD[] = {
|
||||
@@ -640,43 +346,9 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
|
||||
|
||||
switch (msg) {
|
||||
case U8G_DEV_MSG_INIT:
|
||||
dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id);
|
||||
tftio.DataTransferBegin(DATASIZE_8BIT);
|
||||
switch (lcd_id & 0xFFFF) {
|
||||
case 0x8552: // ST7789V
|
||||
WRITE_ESC_SEQUENCE(st7789v_init);
|
||||
setWindow = setWindow_st7789v;
|
||||
break;
|
||||
case 0x9328: // ILI9328
|
||||
WRITE_ESC_SEQUENCE16(ili9328_init);
|
||||
setWindow = setWindow_ili9328;
|
||||
break;
|
||||
case 0x9341: // ILI9341
|
||||
WRITE_ESC_SEQUENCE(ili9341_init);
|
||||
setWindow = setWindow_st7789v;
|
||||
break;
|
||||
case 0x8066: // Anycubic / TronXY TFTs (480x320)
|
||||
WRITE_ESC_SEQUENCE(ili9488_init);
|
||||
setWindow = setWindow_st7789v;
|
||||
break;
|
||||
case 0x7796:
|
||||
WRITE_ESC_SEQUENCE(st7796_init);
|
||||
setWindow = setWindow_st7789v;
|
||||
break;
|
||||
case 0x9488:
|
||||
WRITE_ESC_SEQUENCE(ili9488_init);
|
||||
setWindow = setWindow_st7789v;
|
||||
case 0x0404: // No connected display on FSMC
|
||||
lcd_id = 0;
|
||||
return 0;
|
||||
case 0xFFFF: // No connected display on SPI
|
||||
lcd_id = 0;
|
||||
return 0;
|
||||
default:
|
||||
setWindow = (lcd_id & 0xFF000000) ? setWindow_st7789v : setWindow_ili9328;
|
||||
break;
|
||||
}
|
||||
tftio.DataTransferEnd();
|
||||
dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, NULL);
|
||||
tftio.Init();
|
||||
tftio.InitTFT();
|
||||
|
||||
if (preinit) {
|
||||
preinit = false;
|
||||
@@ -771,14 +443,7 @@ uint8_t u8g_com_hal_tft_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_p
|
||||
case U8G_COM_MSG_STOP: break;
|
||||
case U8G_COM_MSG_INIT:
|
||||
u8g_SetPIOutput(u8g, U8G_PI_RESET);
|
||||
|
||||
u8g_Delay(50);
|
||||
|
||||
tftio.Init();
|
||||
|
||||
if (arg_ptr) {
|
||||
*((uint32_t *)arg_ptr) = tftio.GetID();
|
||||
}
|
||||
isCommand = 0;
|
||||
break;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "../../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
#if HAS_TFT_LVGL_UI
|
||||
|
||||
#include "SPI_TFT.h"
|
||||
#include "pic_manager.h"
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#include "draw_ui.h"
|
||||
|
||||
TFT SPI_TFT;
|
||||
|
||||
// use SPI1 for the spi tft.
|
||||
@@ -39,142 +41,48 @@ void TFT::spi_init(uint8_t spiRate) {
|
||||
tftio.Init();
|
||||
}
|
||||
|
||||
void TFT::LCD_WR_REG(uint8_t cmd) {
|
||||
tftio.WriteReg(cmd);
|
||||
}
|
||||
|
||||
void TFT::LCD_WR_DATA(uint8_t data) {
|
||||
tftio.WriteData(data);
|
||||
}
|
||||
|
||||
void TFT::SetPoint(uint16_t x, uint16_t y, uint16_t point) {
|
||||
if ((x > 480) || (y > 320)) return;
|
||||
|
||||
SetWindows(x, y, 1, 1);
|
||||
setWindow(x, y, 1, 1);
|
||||
tftio.WriteMultiple(point, (uint16_t)1);
|
||||
}
|
||||
|
||||
void TFT::SetWindows(uint16_t x, uint16_t y, uint16_t with, uint16_t height) {
|
||||
tftio.DataTransferBegin(DATASIZE_8BIT);
|
||||
|
||||
LCD_WR_REG(0x2A);
|
||||
LCD_WR_DATA(x >> 8);
|
||||
LCD_WR_DATA(x);
|
||||
LCD_WR_DATA((x + with - 1) >> 8);
|
||||
LCD_WR_DATA((x + with - 1));
|
||||
|
||||
LCD_WR_REG(0x2B);
|
||||
LCD_WR_DATA(y >> 8);
|
||||
LCD_WR_DATA(y);
|
||||
LCD_WR_DATA((y + height - 1) >> 8);
|
||||
LCD_WR_DATA(y + height - 1);
|
||||
|
||||
LCD_WR_REG(0X2C);
|
||||
|
||||
tftio.DataTransferEnd();
|
||||
void TFT::setWindow(uint16_t x, uint16_t y, uint16_t with, uint16_t height) {
|
||||
tftio.set_window(x, y, (x + with - 1), (y + height - 1));
|
||||
}
|
||||
|
||||
void TFT::LCD_init() {
|
||||
TFT_BLK_L;
|
||||
TFT_RST_H;
|
||||
delay(150);
|
||||
TFT_RST_L;
|
||||
delay(150);
|
||||
TFT_RST_H;
|
||||
|
||||
tftio.DataTransferBegin(DATASIZE_8BIT);
|
||||
|
||||
delay(120);
|
||||
LCD_WR_REG(0x11);
|
||||
delay(120);
|
||||
|
||||
LCD_WR_REG(0xF0);
|
||||
LCD_WR_DATA(0xC3);
|
||||
LCD_WR_REG(0xF0);
|
||||
LCD_WR_DATA(0x96);
|
||||
|
||||
LCD_WR_REG(0x36);
|
||||
LCD_WR_DATA(0x28 + TERN0(GRAPHICAL_TFT_ROTATE_180, 0x80));
|
||||
LCD_WR_REG(0x3A);
|
||||
LCD_WR_DATA(0x55);
|
||||
|
||||
LCD_WR_REG(0xB4);
|
||||
LCD_WR_DATA(0x01);
|
||||
LCD_WR_REG(0xB7);
|
||||
LCD_WR_DATA(0xC6);
|
||||
LCD_WR_REG(0xE8);
|
||||
LCD_WR_DATA(0x40);
|
||||
LCD_WR_DATA(0x8A);
|
||||
LCD_WR_DATA(0x00);
|
||||
LCD_WR_DATA(0x00);
|
||||
LCD_WR_DATA(0x29);
|
||||
LCD_WR_DATA(0x19);
|
||||
LCD_WR_DATA(0xA5);
|
||||
LCD_WR_DATA(0x33);
|
||||
LCD_WR_REG(0xC1);
|
||||
LCD_WR_DATA(0x06);
|
||||
LCD_WR_REG(0xC2);
|
||||
LCD_WR_DATA(0xA7);
|
||||
LCD_WR_REG(0xC5);
|
||||
LCD_WR_DATA(0x18);
|
||||
LCD_WR_REG(0xE0); // Positive Voltage Gamma Control
|
||||
LCD_WR_DATA(0xF0);
|
||||
LCD_WR_DATA(0x09);
|
||||
LCD_WR_DATA(0x0B);
|
||||
LCD_WR_DATA(0x06);
|
||||
LCD_WR_DATA(0x04);
|
||||
LCD_WR_DATA(0x15);
|
||||
LCD_WR_DATA(0x2F);
|
||||
LCD_WR_DATA(0x54);
|
||||
LCD_WR_DATA(0x42);
|
||||
LCD_WR_DATA(0x3C);
|
||||
LCD_WR_DATA(0x17);
|
||||
LCD_WR_DATA(0x14);
|
||||
LCD_WR_DATA(0x18);
|
||||
LCD_WR_DATA(0x1B);
|
||||
LCD_WR_REG(0xE1); // Negative Voltage Gamma Control
|
||||
LCD_WR_DATA(0xF0);
|
||||
LCD_WR_DATA(0x09);
|
||||
LCD_WR_DATA(0x0B);
|
||||
LCD_WR_DATA(0x06);
|
||||
LCD_WR_DATA(0x04);
|
||||
LCD_WR_DATA(0x03);
|
||||
LCD_WR_DATA(0x2D);
|
||||
LCD_WR_DATA(0x43);
|
||||
LCD_WR_DATA(0x42);
|
||||
LCD_WR_DATA(0x3B);
|
||||
LCD_WR_DATA(0x16);
|
||||
LCD_WR_DATA(0x14);
|
||||
LCD_WR_DATA(0x17);
|
||||
LCD_WR_DATA(0x1B);
|
||||
LCD_WR_REG(0xF0);
|
||||
LCD_WR_DATA(0x3C);
|
||||
LCD_WR_REG(0xF0);
|
||||
LCD_WR_DATA(0x69);
|
||||
delay(120); // Delay 120ms
|
||||
LCD_WR_REG(0x29); // Display ON
|
||||
|
||||
tftio.DataTransferEnd();
|
||||
|
||||
LCD_clear(0x0000); //
|
||||
tftio.InitTFT();
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, LOW);
|
||||
#endif
|
||||
delay(100);
|
||||
LCD_clear(0x0000);
|
||||
LCD_Draw_Logo();
|
||||
TFT_BLK_H;
|
||||
delay(2000);
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
|
||||
#endif
|
||||
#if HAS_LOGO_IN_FLASH
|
||||
delay(2000);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TFT::LCD_clear(uint16_t color) {
|
||||
SetWindows(0, 0, (TFT_WIDTH) - 1, (TFT_HEIGHT) - 1);
|
||||
setWindow(0, 0, (TFT_WIDTH), (TFT_HEIGHT));
|
||||
tftio.WriteMultiple(color, (uint32_t)(TFT_WIDTH) * (TFT_HEIGHT));
|
||||
}
|
||||
|
||||
extern unsigned char bmp_public_buf[17 * 1024];
|
||||
|
||||
void TFT::LCD_Draw_Logo() {
|
||||
SetWindows(0, 0, TFT_WIDTH, TFT_HEIGHT);
|
||||
for (uint16_t i = 0; i < (TFT_HEIGHT); i ++) {
|
||||
Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (TFT_WIDTH) * 2);
|
||||
tftio.WriteSequence((uint16_t *)bmp_public_buf, TFT_WIDTH);
|
||||
}
|
||||
#if HAS_LOGO_IN_FLASH
|
||||
setWindow(0, 0, TFT_WIDTH, TFT_HEIGHT);
|
||||
for (uint16_t i = 0; i < (TFT_HEIGHT); i ++) {
|
||||
Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (TFT_WIDTH) * 2);
|
||||
tftio.WriteSequence((uint16_t *)bmp_public_buf, TFT_WIDTH);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_TFT_LVGL_UI_SPI
|
||||
#endif // HAS_TFT_LVGL_UI
|
||||
|
@@ -23,29 +23,21 @@
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
#include HAL_PATH(../../HAL, tft/tft_spi.h)
|
||||
#elif ENABLED(TFT_LVGL_UI_FSMC)
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
#endif
|
||||
#if HAS_TFT_LVGL_UI
|
||||
|
||||
#define TFT_RST_H OUT_WRITE(TFT_RESET_PIN, HIGH)
|
||||
#define TFT_RST_L OUT_WRITE(TFT_RESET_PIN, LOW)
|
||||
|
||||
#define TFT_BLK_H OUT_WRITE(LCD_BACKLIGHT_PIN, HIGH)
|
||||
#define TFT_BLK_L OUT_WRITE(LCD_BACKLIGHT_PIN, LOW)
|
||||
#include "../../../tft_io/tft_io.h"
|
||||
|
||||
class TFT {
|
||||
public:
|
||||
TFT_IO tftio;
|
||||
void spi_init(uint8_t spiRate);
|
||||
void LCD_WR_REG(uint8_t cmd);
|
||||
void LCD_WR_DATA(uint8_t data);
|
||||
void SetPoint(uint16_t x, uint16_t y, uint16_t point);
|
||||
void SetWindows(uint16_t x, uint16_t y, uint16_t with, uint16_t height);
|
||||
void setWindow(uint16_t x, uint16_t y, uint16_t with, uint16_t height);
|
||||
void LCD_init();
|
||||
void LCD_clear(uint16_t color);
|
||||
void LCD_Draw_Logo();
|
||||
};
|
||||
|
||||
extern TFT SPI_TFT;
|
||||
|
||||
#endif // HAS_TFT_LVGL_UI
|
||||
|
@@ -23,9 +23,7 @@
|
||||
|
||||
#if HAS_TFT_LVGL_UI
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
#include "SPI_TFT.h"
|
||||
#endif
|
||||
#include "SPI_TFT.h"
|
||||
|
||||
#include "lv_conf.h"
|
||||
#include "draw_ui.h"
|
||||
@@ -77,7 +75,7 @@ void lv_draw_error_message(PGM_P const msg) {
|
||||
lv_task_handler();
|
||||
#endif
|
||||
|
||||
TERN(TFT_LVGL_UI_SPI, SPI_TFT.LCD_clear, LCD_Clear)(0x0000);
|
||||
SPI_TFT.LCD_clear(0x0000);
|
||||
if (msg) disp_string((TFT_WIDTH - strlen(msg) * 16) / 2, 100, msg, 0xFFFF, 0x0000);
|
||||
disp_string((TFT_WIDTH - strlen("PRINTER HALTED") * 16) / 2, 140, "PRINTER HALTED", 0xFFFF, 0x0000);
|
||||
disp_string((TFT_WIDTH - strlen("Please Reset") * 16) / 2, 180, "Please Reset", 0xFFFF, 0x0000);
|
||||
|
@@ -46,7 +46,8 @@
|
||||
|
||||
extern lv_group_t * g;
|
||||
static lv_obj_t * scr;
|
||||
static lv_obj_t *labelExt1, * labelExt2, * labelFan, * labelZpos, * labelTime;
|
||||
static lv_obj_t *labelExt1, * labelFan, * labelZpos, * labelTime;
|
||||
TERN_(HAS_MULTI_EXTRUDER, static lv_obj_t *labelExt2;)
|
||||
static lv_obj_t *labelPause, * labelStop, * labelOperat;
|
||||
static lv_obj_t * bar1, *bar1ValueText;
|
||||
static lv_obj_t * buttonPause, *buttonOperat, *buttonStop;
|
||||
@@ -137,9 +138,6 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) {
|
||||
}
|
||||
|
||||
void lv_draw_printing(void) {
|
||||
lv_obj_t *buttonExt1, *buttonExt2, *buttonFanstate, *buttonZpos, *buttonTime;
|
||||
TERN_(HAS_HEATED_BED, lv_obj_t * buttonBedstate);
|
||||
|
||||
disp_state_stack._disp_index = 0;
|
||||
ZERO(disp_state_stack._disp_state);
|
||||
disp_state_stack._disp_state[disp_state_stack._disp_index] = PRINTING_UI;
|
||||
@@ -162,16 +160,16 @@ void lv_draw_printing(void) {
|
||||
lv_refr_now(lv_refr_get_disp_refreshing());
|
||||
|
||||
// Create image buttons
|
||||
buttonExt1 = lv_img_create(scr, NULL);
|
||||
lv_obj_t *buttonExt1 = lv_img_create(scr, NULL);
|
||||
#if HAS_MULTI_EXTRUDER
|
||||
buttonExt2 = lv_img_create(scr, NULL);
|
||||
lv_obj_t *buttonExt2 = lv_img_create(scr, NULL);
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
buttonBedstate = lv_img_create(scr, NULL);
|
||||
lv_obj_t *buttonBedstate = lv_img_create(scr, NULL);
|
||||
#endif
|
||||
buttonFanstate = lv_img_create(scr, NULL);
|
||||
buttonTime = lv_img_create(scr, NULL);
|
||||
buttonZpos = lv_img_create(scr, NULL);
|
||||
lv_obj_t *buttonFanstate = lv_img_create(scr, NULL);
|
||||
lv_obj_t *buttonTime = lv_img_create(scr, NULL);
|
||||
lv_obj_t *buttonZpos = lv_img_create(scr, NULL);
|
||||
buttonPause = lv_imgbtn_create(scr, NULL);
|
||||
buttonStop = lv_imgbtn_create(scr, NULL);
|
||||
buttonOperat = lv_imgbtn_create(scr, NULL);
|
||||
|
@@ -23,9 +23,7 @@
|
||||
|
||||
#if HAS_TFT_LVGL_UI
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
#include "SPI_TFT.h"
|
||||
#endif
|
||||
#include "SPI_TFT.h"
|
||||
|
||||
#include "tft_lvgl_configuration.h"
|
||||
|
||||
@@ -165,7 +163,7 @@ void gCfgItems_init() {
|
||||
W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[4], OTHERS_COMMAND_ADDR_4, 100);
|
||||
}
|
||||
|
||||
const byte rot = TERN0(GRAPHICAL_TFT_ROTATE_180, 0xEE);
|
||||
const byte rot = (TFT_ROTATION & TFT_ROTATE_180) ? 0xEE : 0x00;
|
||||
if (gCfgItems.disp_rotation_180 != rot) {
|
||||
gCfgItems.disp_rotation_180 = rot;
|
||||
update_spi_flash();
|
||||
@@ -655,12 +653,7 @@ char *creat_title_text() {
|
||||
}
|
||||
|
||||
card.setIndex((gPicturePreviewStart + To_pre_view) + size * row + 8);
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
SPI_TFT.SetWindows(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
#else
|
||||
LCD_setWindowArea(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
LCD_WriteRAM_Prepare();
|
||||
#endif
|
||||
SPI_TFT.setWindow(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
|
||||
j = i = 0;
|
||||
|
||||
@@ -673,20 +666,11 @@ char *creat_title_text() {
|
||||
}
|
||||
if (j >= 400) break;
|
||||
}
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
for (i = 0; i < 400; i += 2) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full;
|
||||
}
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)bmp_public_buf, 200);
|
||||
#else
|
||||
for (i = 0; i < 400;) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full; //gCfgItems.preview_bk_color;
|
||||
LCD_IO_WriteData(*p_index);
|
||||
i += 2;
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < 400; i += 2) {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full;
|
||||
}
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)bmp_public_buf, 200);
|
||||
#if HAS_BAK_VIEW_IN_FLASH
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
if (row < 20) W25QXX.SPI_FLASH_SectorErase(BAK_VIEW_ADDR_TFT35 + row * 4096);
|
||||
@@ -768,7 +752,7 @@ char *creat_title_text() {
|
||||
|
||||
card.setIndex((PREVIEW_LITTLE_PIC_SIZE + To_pre_view) + size * row + 8);
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
SPI_TFT.SetWindows(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
SPI_TFT.setWindow(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
#else
|
||||
LCD_setWindowArea(xpos_pixel, ypos_pixel + row, 200, 1);
|
||||
LCD_WriteRAM_Prepare();
|
||||
@@ -901,34 +885,9 @@ char *creat_title_text() {
|
||||
default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k
|
||||
#endif
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
SPI_TFT.SetWindows(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)(bmp_public_buf), DEFAULT_VIEW_MAX_SIZE / 20);
|
||||
#else
|
||||
int x_off = 0;
|
||||
uint16_t temp_p;
|
||||
int i = 0;
|
||||
uint16_t *p_index;
|
||||
LCD_setWindowArea(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
|
||||
SPI_TFT.setWindow(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)(bmp_public_buf), DEFAULT_VIEW_MAX_SIZE / 20);
|
||||
|
||||
LCD_WriteRAM_Prepare();
|
||||
|
||||
for (int _y = y_off * 20; _y < (y_off + 1) * 20; _y++) {
|
||||
for (x_off = 0; x_off < 200; x_off++) {
|
||||
if (sel == 1) {
|
||||
temp_p = (uint16_t)(bmp_public_buf[i] | bmp_public_buf[i + 1] << 8);
|
||||
p_index = &temp_p;
|
||||
}
|
||||
else {
|
||||
p_index = (uint16_t *)(&bmp_public_buf[i]);
|
||||
}
|
||||
if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full; //gCfgItems.preview_bk_color;
|
||||
LCD_IO_WriteData(*p_index);
|
||||
i += 2;
|
||||
}
|
||||
if (i >= 8000) break;
|
||||
}
|
||||
#endif // TFT_LVGL_UI_SPI
|
||||
y_off++;
|
||||
}
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
|
@@ -23,9 +23,7 @@
|
||||
|
||||
#if HAS_TFT_LVGL_UI
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
#include "SPI_TFT.h"
|
||||
#endif
|
||||
#include "SPI_TFT.h"
|
||||
|
||||
#include "tft_lvgl_configuration.h"
|
||||
#include "draw_ready_print.h"
|
||||
@@ -626,10 +624,8 @@ static const uint16_t ASCII_Table_16x24[] PROGMEM = {
|
||||
void disp_char_1624(uint16_t x, uint16_t y, uint8_t c, uint16_t charColor, uint16_t bkColor) {
|
||||
for (uint16_t i = 0; i < 24; i++) {
|
||||
const uint16_t tmp_char = pgm_read_word(&ASCII_Table_16x24[((c - 0x20) * 24) + i]);
|
||||
for (uint16_t j = 0; j < 16; j++) {
|
||||
TERN(TFT_LVGL_UI_SPI, SPI_TFT.SetPoint, tft_set_point)
|
||||
(x + j, y + i, ((tmp_char >> j) & 0x01) ? charColor : bkColor);
|
||||
}
|
||||
for (uint16_t j = 0; j < 16; j++)
|
||||
SPI_TFT.SetPoint(x + j, y + i, ((tmp_char >> j) & 0x01) ? charColor : bkColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,7 +639,7 @@ void disp_string(uint16_t x, uint16_t y, const char * string, uint16_t charColor
|
||||
|
||||
//static lv_obj_t * scr_test;
|
||||
void disp_assets_update() {
|
||||
TERN(TFT_LVGL_UI_SPI,, LCD_Clear(0x0000));
|
||||
SPI_TFT.LCD_clear(0x0000);
|
||||
disp_string(100, 140, "Assets Updating...", 0xFFFF, 0x0000);
|
||||
}
|
||||
|
||||
|
@@ -266,19 +266,24 @@ void spiFlashErase_PIC() {
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
//erase 0x001000 -64K
|
||||
for (pic_sectorcnt = 0; pic_sectorcnt < (64 - 4) / 4; pic_sectorcnt++) {
|
||||
watchdog_refresh();
|
||||
W25QXX.SPI_FLASH_SectorErase(PICINFOADDR + pic_sectorcnt * 4 * 1024);
|
||||
}
|
||||
//erase 64K -- 6M
|
||||
for (pic_sectorcnt = 0; pic_sectorcnt < (PIC_SIZE_xM * 1024 / 64 - 1); pic_sectorcnt++)
|
||||
for (pic_sectorcnt = 0; pic_sectorcnt < (PIC_SIZE_xM * 1024 / 64 - 1); pic_sectorcnt++) {
|
||||
watchdog_refresh();
|
||||
W25QXX.SPI_FLASH_BlockErase((pic_sectorcnt + 1) * 64 * 1024);
|
||||
}
|
||||
}
|
||||
|
||||
#if HAS_SPI_FLASH_FONT
|
||||
void spiFlashErase_FONT() {
|
||||
volatile uint32_t Font_sectorcnt = 0;
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
for (Font_sectorcnt = 0; Font_sectorcnt < 32-1; Font_sectorcnt++)
|
||||
for (Font_sectorcnt = 0; Font_sectorcnt < 32-1; Font_sectorcnt++) {
|
||||
watchdog_refresh();
|
||||
W25QXX.SPI_FLASH_BlockErase(FONTINFOADDR + Font_sectorcnt * 64 * 1024);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -410,6 +415,7 @@ uint8_t public_buf[512];
|
||||
return;
|
||||
}
|
||||
|
||||
watchdog_refresh();
|
||||
disp_assets_update_progress(fn);
|
||||
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
@@ -422,18 +428,21 @@ uint8_t public_buf[512];
|
||||
totalSizeLoaded += pfileSize;
|
||||
if (assetType == ASSET_TYPE_LOGO) {
|
||||
do {
|
||||
watchdog_refresh();
|
||||
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
|
||||
Pic_Logo_Write((uint8_t *)fn, public_buf, pbr);
|
||||
} while (pbr >= BMP_WRITE_BUF_LEN);
|
||||
}
|
||||
else if (assetType == ASSET_TYPE_TITLE_LOGO) {
|
||||
do {
|
||||
watchdog_refresh();
|
||||
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
|
||||
Pic_TitleLogo_Write((uint8_t *)fn, public_buf, pbr);
|
||||
} while (pbr >= BMP_WRITE_BUF_LEN);
|
||||
}
|
||||
else if (assetType == ASSET_TYPE_G_PREVIEW) {
|
||||
do {
|
||||
watchdog_refresh();
|
||||
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
|
||||
default_view_Write(public_buf, pbr);
|
||||
} while (pbr >= BMP_WRITE_BUF_LEN);
|
||||
@@ -443,6 +452,7 @@ uint8_t public_buf[512];
|
||||
SPIFlash.beginWrite(Pic_Write_Addr);
|
||||
#if HAS_SPI_FLASH_COMPRESSION
|
||||
do {
|
||||
watchdog_refresh();
|
||||
pbr = file.read(public_buf, SPI_FLASH_PageSize);
|
||||
TERN_(MARLIN_DEV_MODE, totalSizes += pbr);
|
||||
SPIFlash.writeData(public_buf, SPI_FLASH_PageSize);
|
||||
@@ -463,6 +473,7 @@ uint8_t public_buf[512];
|
||||
else if (assetType == ASSET_TYPE_FONT) {
|
||||
Pic_Write_Addr = UNIGBK_FLASH_ADDR;
|
||||
do {
|
||||
watchdog_refresh();
|
||||
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
|
||||
W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr);
|
||||
Pic_Write_Addr += pbr;
|
||||
@@ -482,9 +493,11 @@ uint8_t public_buf[512];
|
||||
|
||||
disp_assets_update();
|
||||
disp_assets_update_progress("Erasing pics...");
|
||||
watchdog_refresh();
|
||||
spiFlashErase_PIC();
|
||||
#if HAS_SPI_FLASH_FONT
|
||||
disp_assets_update_progress("Erasing fonts...");
|
||||
watchdog_refresh();
|
||||
spiFlashErase_FONT();
|
||||
#endif
|
||||
|
||||
|
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_FSMC)
|
||||
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
TFT_IO tftio;
|
||||
|
||||
void LCD_IO_Init(uint8_t cs, uint8_t rs);
|
||||
void LCD_IO_WriteData(uint16_t RegValue);
|
||||
void LCD_IO_WriteReg(uint16_t Reg);
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
void LCD_IO_WriteMultiple(uint16_t data, uint32_t count);
|
||||
void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
|
||||
#endif
|
||||
|
||||
void LCD_IO_Init(uint8_t cs, uint8_t rs) {
|
||||
tftio.Init();
|
||||
}
|
||||
|
||||
void LCD_IO_WriteData(uint16_t RegValue) {
|
||||
tftio.WriteData(RegValue);
|
||||
}
|
||||
|
||||
void LCD_IO_WriteReg(uint16_t Reg) {
|
||||
tftio.WriteReg(Reg);
|
||||
}
|
||||
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
void LCD_IO_WriteMultiple(uint16_t color, uint32_t count) {
|
||||
tftio.WriteMultiple(color, count);
|
||||
}
|
||||
|
||||
void LCD_IO_WriteSequence(uint16_t *data, uint16_t length) {
|
||||
tftio.WriteSequence(data, length);
|
||||
}
|
||||
#endif // LCD_USE_DMA_FSMC
|
||||
|
||||
#endif // HAS_TFT_LVGL_UI
|
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* C-declarations for C++ */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* C-declarations for C++ */
|
||||
#endif
|
@@ -29,9 +29,7 @@
|
||||
|
||||
#if HAS_TFT_LVGL_UI
|
||||
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
#include "SPI_TFT.h"
|
||||
#endif
|
||||
#include "SPI_TFT.h"
|
||||
|
||||
#include "tft_lvgl_configuration.h"
|
||||
#include "draw_ready_print.h"
|
||||
@@ -74,24 +72,6 @@ lv_group_t* g;
|
||||
uint16_t DeviceCode = 0x9488;
|
||||
extern uint8_t sel_id;
|
||||
|
||||
#define SetCs
|
||||
#define ClrCs
|
||||
|
||||
#define HDP 799 // Horizontal Display Period
|
||||
#define HT 1000 // Horizontal Total
|
||||
#define HPS 51 // LLINE Pulse Start Position
|
||||
#define LPS 3 // Horizontal Display Period Start Position
|
||||
#define HPW 8 // LLINE Pulse Width
|
||||
|
||||
#define VDP 479 // Vertical Display Period
|
||||
#define VT 530 // Vertical Total
|
||||
#define VPS 24 // LFRAME Pulse Start Position
|
||||
#define FPS 23 // Vertical Display Period Start Positio
|
||||
#define VPW 3 // LFRAME Pulse Width
|
||||
|
||||
#define MAX_HZ_POSX HDP+1
|
||||
#define MAX_HZ_POSY VDP+1
|
||||
|
||||
extern uint8_t gcode_preview_over, flash_preview_begin, default_preview_flg;
|
||||
|
||||
uint8_t bmp_public_buf[17 * 1024];
|
||||
@@ -125,317 +105,7 @@ void SysTick_Callback() {
|
||||
}
|
||||
}
|
||||
|
||||
#if DISABLED(TFT_LVGL_UI_SPI)
|
||||
|
||||
extern void LCD_IO_Init(uint8_t cs, uint8_t rs);
|
||||
extern void LCD_IO_WriteData(uint16_t RegValue);
|
||||
extern void LCD_IO_WriteReg(uint16_t Reg);
|
||||
|
||||
extern void LCD_IO_WriteMultiple(uint16_t color, uint32_t count);
|
||||
void tft_set_cursor(uint16_t x, uint16_t y) {
|
||||
LCD_IO_WriteReg(0x002A);
|
||||
LCD_IO_WriteData(x >> 8);
|
||||
LCD_IO_WriteData(x & 0x00FF);
|
||||
LCD_IO_WriteData(x >> 8);
|
||||
LCD_IO_WriteData(x & 0x00FF);
|
||||
//ILI9488_WriteData(0x01);
|
||||
//ILI9488_WriteData(0xDF);
|
||||
LCD_IO_WriteReg(0x002B);
|
||||
LCD_IO_WriteData(y >> 8);
|
||||
LCD_IO_WriteData(y & 0x00FF);
|
||||
LCD_IO_WriteData(y >> 8);
|
||||
LCD_IO_WriteData(y & 0x00FF);
|
||||
//ILI9488_WriteData(0x01);
|
||||
//ILI9488_WriteData(0x3F);
|
||||
}
|
||||
|
||||
void LCD_WriteRAM_Prepare(void) {
|
||||
#if 0
|
||||
switch (DeviceCode) {
|
||||
case 0x9325: case 0x9328: case 0x8989: {
|
||||
ClrCs
|
||||
LCD->LCD_REG = R34;
|
||||
SetCs
|
||||
} break;
|
||||
default: LCD_WrtReg(0x002C);
|
||||
}
|
||||
#else
|
||||
LCD_IO_WriteReg(0x002C);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tft_set_point(uint16_t x, uint16_t y, uint16_t point) {
|
||||
//if (DeviceCode == 0x9488) {
|
||||
if (x > (TFT_WIDTH) || y > (TFT_HEIGHT)) return;
|
||||
//}
|
||||
tft_set_cursor(x, y);
|
||||
|
||||
LCD_WriteRAM_Prepare();
|
||||
//LCD_WriteRAM(point);
|
||||
LCD_IO_WriteData(point);
|
||||
}
|
||||
|
||||
void LCD_WriteReg(uint16_t LCD_Reg, uint16_t LCD_RegValue) {
|
||||
/* Write 16-bit Index, then Write Reg */
|
||||
ClrCs
|
||||
LCD_IO_WriteReg(LCD_Reg);
|
||||
/* Write 16-bit Reg */
|
||||
LCD_IO_WriteData(LCD_RegValue);
|
||||
SetCs
|
||||
}
|
||||
|
||||
void LCD_setWindowArea(uint16_t StartX, uint16_t StartY, uint16_t width, uint16_t heigh) {
|
||||
uint16_t s_h, s_l, e_h, e_l;
|
||||
uint16_t xEnd, yEnd;
|
||||
xEnd = StartX + width;
|
||||
yEnd = StartY + heigh - 1;
|
||||
if (DeviceCode == 0x8989) {
|
||||
/*LCD_WriteReg(0x0044, (StartX & 0xFF) | (xEnd << 8));
|
||||
LCD_WriteReg(0x0045, StartY);
|
||||
LCD_WriteReg(0x0046, yEnd);*/
|
||||
LCD_WriteReg(0x0044, (StartY & 0xFF) | (yEnd << 8));
|
||||
LCD_WriteReg(0x0045, StartX);
|
||||
LCD_WriteReg(0x0046, xEnd);
|
||||
}
|
||||
else if (DeviceCode == 0x9488) {
|
||||
s_h = (StartX >> 8) & 0x00FF;
|
||||
s_l = StartX & 0x00FF;
|
||||
e_h = ((StartX + width - 1) >> 8) & 0x00FF;
|
||||
e_l = (StartX + width - 1) & 0x00FF;
|
||||
|
||||
LCD_IO_WriteReg(0x002A);
|
||||
LCD_IO_WriteData(s_h);
|
||||
LCD_IO_WriteData(s_l);
|
||||
LCD_IO_WriteData(e_h);
|
||||
LCD_IO_WriteData(e_l);
|
||||
|
||||
s_h = (StartY >> 8) & 0x00FF;
|
||||
s_l = StartY & 0x00FF;
|
||||
e_h = ((StartY + heigh - 1) >> 8) & 0x00FF;
|
||||
e_l = (StartY + heigh - 1) & 0x00FF;
|
||||
|
||||
LCD_IO_WriteReg(0x002B);
|
||||
LCD_IO_WriteData(s_h);
|
||||
LCD_IO_WriteData(s_l);
|
||||
LCD_IO_WriteData(e_h);
|
||||
LCD_IO_WriteData(e_l);
|
||||
}
|
||||
else if ((DeviceCode == 0x9325) || (DeviceCode == 0x9328) || (DeviceCode == 0x1505)) {
|
||||
/* LCD_WriteReg(0x0050, StartX);
|
||||
LCD_WriteReg(0x0052, StartY);
|
||||
LCD_WriteReg(0x0051, xEnd);
|
||||
LCD_WriteReg(0x0053, yEnd);*/
|
||||
LCD_WriteReg(0x0050, StartY); // Specify the start/end positions of the window address in the horizontal direction by an address unit
|
||||
LCD_WriteReg(0x0051, yEnd); // Specify the start positions of the window address in the vertical direction by an address unit
|
||||
LCD_WriteReg(0x0052, (TFT_HEIGHT) - xEnd);
|
||||
LCD_WriteReg(0x0053, (TFT_HEIGHT) - StartX - 1); // Specify the end positions of the window address in the vertical direction by an address unit
|
||||
|
||||
}
|
||||
else {
|
||||
s_h = (StartX >> 8) & 0xFF;
|
||||
s_l = StartX & 0xFF;
|
||||
e_h = ((StartX + width - 1) >> 8) & 0xFF;
|
||||
e_l = (StartX + width - 1) & 0xFF;
|
||||
|
||||
LCD_IO_WriteReg(0x2A);
|
||||
LCD_IO_WriteData(s_h);
|
||||
LCD_IO_WriteData(s_l);
|
||||
LCD_IO_WriteData(e_h);
|
||||
LCD_IO_WriteData(e_l);
|
||||
|
||||
s_h = (StartY >> 8) & 0xFF;
|
||||
s_l = StartY & 0xFF;
|
||||
e_h = ((StartY + heigh - 1) >> 8) & 0xFF;
|
||||
e_l = (StartY + heigh - 1) & 0xFF;
|
||||
|
||||
LCD_IO_WriteReg(0x2B);
|
||||
LCD_IO_WriteData(s_h);
|
||||
LCD_IO_WriteData(s_l);
|
||||
LCD_IO_WriteData(e_h);
|
||||
LCD_IO_WriteData(e_l);
|
||||
}
|
||||
}
|
||||
|
||||
void LCD_Clear(uint16_t Color) {
|
||||
uint32_t index = 0;
|
||||
unsigned int count;
|
||||
|
||||
if (DeviceCode == 0x9488) {
|
||||
tft_set_cursor(0, 0);
|
||||
LCD_setWindowArea(0, 0, TFT_WIDTH, TFT_HEIGHT);
|
||||
LCD_WriteRAM_Prepare();
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
LCD_IO_WriteMultiple(Color, (TFT_WIDTH) * (TFT_HEIGHT));
|
||||
#else
|
||||
//index = (TFT_HEIGHT) / 2 * (TFT_WIDTH);
|
||||
for (index = 0; index < (TFT_HEIGHT) * (TFT_WIDTH); index++)
|
||||
LCD_IO_WriteData(Color);
|
||||
#endif
|
||||
//LCD_IO_WriteMultiple(Color, (TFT_WIDTH) * (TFT_HEIGHT));
|
||||
//while(index --) LCD_IO_WriteData(Color);
|
||||
}
|
||||
else if (DeviceCode == 0x5761) {
|
||||
LCD_IO_WriteReg(0x002A);
|
||||
LCD_IO_WriteData(0);
|
||||
LCD_IO_WriteData(0);
|
||||
LCD_IO_WriteData(HDP >> 8);
|
||||
LCD_IO_WriteData(HDP & 0x00FF);
|
||||
LCD_IO_WriteReg(0x002B);
|
||||
LCD_IO_WriteData(0);
|
||||
LCD_IO_WriteData(0);
|
||||
LCD_IO_WriteData(VDP >> 8);
|
||||
LCD_IO_WriteData(VDP & 0x00FF);
|
||||
LCD_IO_WriteReg(0x002C);
|
||||
LCD_IO_WriteReg(0x002C);
|
||||
for (count = 0; count < (HDP + 1) * (VDP + 1); count++)
|
||||
LCD_IO_WriteData(Color);
|
||||
}
|
||||
else {
|
||||
tft_set_cursor(0, 0);
|
||||
LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */
|
||||
for (index = 0; index < 76800; index++)
|
||||
LCD_IO_WriteData(Color);
|
||||
}
|
||||
}
|
||||
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
extern TFT_IO tftio;
|
||||
void fsmc_tft_init() {
|
||||
uint16_t i;
|
||||
|
||||
TERN_(HAS_LCD_CONTRAST, refresh_contrast());
|
||||
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
dma_init(FSMC_DMA_DEV);
|
||||
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
|
||||
dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM);
|
||||
#endif
|
||||
|
||||
LCD_IO_Init(FSMC_CS_PIN, FSMC_RS_PIN);
|
||||
|
||||
_delay_ms(5);
|
||||
|
||||
DeviceCode = tftio.GetID() & 0xFFFF;
|
||||
// Chitu and others
|
||||
if (DeviceCode == 0x8066) DeviceCode = 0x9488;
|
||||
|
||||
if (DeviceCode == 0x9488) {
|
||||
LCD_IO_WriteReg(0x00E0);
|
||||
LCD_IO_WriteData(0x0000);
|
||||
LCD_IO_WriteData(0x0007);
|
||||
LCD_IO_WriteData(0x000F);
|
||||
LCD_IO_WriteData(0x000D);
|
||||
LCD_IO_WriteData(0x001B);
|
||||
LCD_IO_WriteData(0x000A);
|
||||
LCD_IO_WriteData(0x003C);
|
||||
LCD_IO_WriteData(0x0078);
|
||||
LCD_IO_WriteData(0x004A);
|
||||
LCD_IO_WriteData(0x0007);
|
||||
LCD_IO_WriteData(0x000E);
|
||||
LCD_IO_WriteData(0x0009);
|
||||
LCD_IO_WriteData(0x001B);
|
||||
LCD_IO_WriteData(0x001E);
|
||||
LCD_IO_WriteData(0x000F);
|
||||
|
||||
LCD_IO_WriteReg(0x00E1);
|
||||
LCD_IO_WriteData(0x0000);
|
||||
LCD_IO_WriteData(0x0022);
|
||||
LCD_IO_WriteData(0x0024);
|
||||
LCD_IO_WriteData(0x0006);
|
||||
LCD_IO_WriteData(0x0012);
|
||||
LCD_IO_WriteData(0x0007);
|
||||
LCD_IO_WriteData(0x0036);
|
||||
LCD_IO_WriteData(0x0047);
|
||||
LCD_IO_WriteData(0x0047);
|
||||
LCD_IO_WriteData(0x0006);
|
||||
LCD_IO_WriteData(0x000A);
|
||||
LCD_IO_WriteData(0x0007);
|
||||
LCD_IO_WriteData(0x0030);
|
||||
LCD_IO_WriteData(0x0037);
|
||||
LCD_IO_WriteData(0x000F);
|
||||
|
||||
LCD_IO_WriteReg(0x00C0);
|
||||
LCD_IO_WriteData(0x0010);
|
||||
LCD_IO_WriteData(0x0010);
|
||||
|
||||
LCD_IO_WriteReg(0x00C1);
|
||||
LCD_IO_WriteData(0x0041);
|
||||
|
||||
LCD_IO_WriteReg(0x00C5);
|
||||
LCD_IO_WriteData(0x0000);
|
||||
LCD_IO_WriteData(0x0022);
|
||||
LCD_IO_WriteData(0x0080);
|
||||
|
||||
LCD_IO_WriteReg(0x0036);
|
||||
LCD_IO_WriteData(TERN(GRAPHICAL_TFT_ROTATE_180, 0xE8, 0x0068));
|
||||
|
||||
LCD_IO_WriteReg(0x003A); //Interface Mode Control
|
||||
LCD_IO_WriteData(0x0055);
|
||||
|
||||
LCD_IO_WriteReg(0x00B0); //Interface Mode Control
|
||||
LCD_IO_WriteData(0x0000);
|
||||
LCD_IO_WriteReg(0x00B1); //Frame rate 70HZ
|
||||
LCD_IO_WriteData(0x00B0);
|
||||
LCD_IO_WriteData(0x0011);
|
||||
LCD_IO_WriteReg(0x00B4);
|
||||
LCD_IO_WriteData(0x0002);
|
||||
LCD_IO_WriteReg(0x00B6); //RGB/MCU Interface Control
|
||||
LCD_IO_WriteData(0x0002);
|
||||
LCD_IO_WriteData(0x0042);
|
||||
|
||||
LCD_IO_WriteReg(0x00B7);
|
||||
LCD_IO_WriteData(0x00C6);
|
||||
|
||||
//WriteComm(0xBE);
|
||||
//WriteData(0x00);
|
||||
//WriteData(0x04);
|
||||
|
||||
LCD_IO_WriteReg(0x00E9);
|
||||
LCD_IO_WriteData(0x0000);
|
||||
|
||||
LCD_IO_WriteReg(0x00F7);
|
||||
LCD_IO_WriteData(0x00A9);
|
||||
LCD_IO_WriteData(0x0051);
|
||||
LCD_IO_WriteData(0x002C);
|
||||
LCD_IO_WriteData(0x0082);
|
||||
|
||||
LCD_IO_WriteReg(0x0011);
|
||||
for (i = 0; i < 65535; i++) { /* do nothing */ }
|
||||
LCD_IO_WriteReg(0x0029);
|
||||
|
||||
LCD_setWindowArea(0, 0, TFT_WIDTH, TFT_HEIGHT);
|
||||
|
||||
OUT_WRITE(LCD_BACKLIGHT_PIN, LOW);
|
||||
LCD_Clear(0x0000);
|
||||
|
||||
TERN_(HAS_LOGO_IN_FLASH, lcd_draw_logo());
|
||||
|
||||
OUT_WRITE(LCD_BACKLIGHT_PIN, HIGH);
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
extern void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
|
||||
|
||||
void lcd_draw_logo() {
|
||||
LCD_setWindowArea(0, 0, TFT_WIDTH, TFT_HEIGHT);
|
||||
LCD_WriteRAM_Prepare();
|
||||
|
||||
for (uint16_t i = 0; i < (TFT_HEIGHT); i ++) {
|
||||
Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (TFT_WIDTH) * 2);
|
||||
#ifdef LCD_USE_DMA_FSMC
|
||||
LCD_IO_WriteSequence((uint16_t *)bmp_public_buf, TFT_WIDTH);
|
||||
#else
|
||||
int index = 0;,x_off = 0;
|
||||
for (x_off = 0; x_off < TFT_WIDTH; x_off++) {
|
||||
LCD_IO_WriteData((uint16_t)bmp_public_buf[index]);
|
||||
index += 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !TFT_LVGL_UI_SPI
|
||||
extern uint8_t bmp_public_buf[17 * 1024];
|
||||
|
||||
void tft_lvgl_init() {
|
||||
|
||||
@@ -448,17 +118,16 @@ void tft_lvgl_init() {
|
||||
disp_language_init();
|
||||
|
||||
//init tft first!
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
SPI_TFT.spi_init(SPI_FULL_SPEED);
|
||||
SPI_TFT.LCD_init();
|
||||
#else
|
||||
fsmc_tft_init();
|
||||
#endif
|
||||
SPI_TFT.spi_init(SPI_FULL_SPEED);
|
||||
SPI_TFT.LCD_init();
|
||||
|
||||
//spi_flash_read_test();
|
||||
#if ENABLED(SDSUPPORT)
|
||||
watchdog_refresh();
|
||||
UpdateAssets();
|
||||
#endif
|
||||
|
||||
watchdog_refresh();
|
||||
mks_test_get();
|
||||
|
||||
touch.Init();
|
||||
@@ -548,41 +217,18 @@ void tft_lvgl_init() {
|
||||
}
|
||||
|
||||
void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) {
|
||||
#if ENABLED(TFT_LVGL_UI_SPI)
|
||||
uint16_t i, width, height;
|
||||
uint16_t i, width, height;
|
||||
|
||||
width = area->x2 - area->x1 + 1;
|
||||
height = area->y2 - area->y1 + 1;
|
||||
width = area->x2 - area->x1 + 1;
|
||||
height = area->y2 - area->y1 + 1;
|
||||
|
||||
SPI_TFT.SetWindows((uint16_t)area->x1, (uint16_t)area->y1, width, height);
|
||||
for (i = 0; i < height; i++) {
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)(color_p + width * i), width);
|
||||
}
|
||||
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
SPI_TFT.setWindow((uint16_t)area->x1, (uint16_t)area->y1, width, height);
|
||||
for (i = 0; i < height; i++) {
|
||||
SPI_TFT.tftio.WriteSequence((uint16_t*)(color_p + width * i), width);
|
||||
}
|
||||
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
|
||||
#else // !TFT_LVGL_UI_SPI
|
||||
|
||||
#if 1
|
||||
uint16_t i, width, height;
|
||||
//uint16_t clr_temp;
|
||||
width = area->x2 - area->x1 + 1;
|
||||
height = area->y2 - area->y1 + 1;
|
||||
LCD_setWindowArea((uint16_t)area->x1, (uint16_t)area->y1, width, height);
|
||||
LCD_WriteRAM_Prepare();
|
||||
for (i = 0; i < width * height - 2; i++) {
|
||||
//clr_temp = (uint16_t)(((uint16_t)color_p->ch.red << 11)
|
||||
//| ((uint16_t)color_p->ch.green << 5)
|
||||
//| ((uint16_t)color_p->ch.blue));
|
||||
LCD_IO_WriteData(color_p->full);
|
||||
color_p++;
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
#endif
|
||||
|
||||
#endif // !TFT_LVGL_UI_SPI
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
}
|
||||
|
||||
#define TICK_CYCLE 1
|
||||
@@ -599,7 +245,7 @@ static bool get_point(int16_t *x, int16_t *y) {
|
||||
*y = int16_t((int32_t(*y) * XPT2046_Y_CALIBRATION) >> 16) + XPT2046_Y_OFFSET;
|
||||
}
|
||||
|
||||
#if ENABLED(GRAPHICAL_TFT_ROTATE_180)
|
||||
#if (TFT_ROTATION & TFT_ROTATE_180)
|
||||
*x = int16_t((TFT_WIDTH) - (int)(*x));
|
||||
*y = int16_t((TFT_HEIGHT) - (int)(*y));
|
||||
#endif
|
||||
@@ -799,39 +445,39 @@ void lv_encoder_pin_init() {
|
||||
//static const int8_t encoderDirection = 1;
|
||||
//static int16_t enc_Direction;
|
||||
void lv_update_encoder() {
|
||||
static uint8_t buttons;
|
||||
static uint32_t encoder_time1;
|
||||
uint32_t tmpTime, diffTime = 0;
|
||||
tmpTime = millis();
|
||||
diffTime = getTickDiff(tmpTime, encoder_time1);
|
||||
if (diffTime > 50) {
|
||||
|
||||
#if ANY_BUTTON(EN1, EN2, ENC, BACK)
|
||||
|
||||
uint8_t newbutton = 0;
|
||||
|
||||
#if BUTTON_EXISTS(EN1)
|
||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
||||
#endif
|
||||
#if BUTTON_EXISTS(EN2)
|
||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
||||
#endif
|
||||
#if BUTTON_EXISTS(ENC)
|
||||
if (BUTTON_PRESSED(ENC)) newbutton |= EN_C;
|
||||
#endif
|
||||
#if BUTTON_EXISTS(BACK)
|
||||
if (BUTTON_PRESSED(BACK)) newbutton |= EN_D;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
constexpr uint8_t newbutton = 0;
|
||||
|
||||
#endif
|
||||
|
||||
buttons = newbutton;
|
||||
|
||||
#if HAS_ENCODER_WHEEL
|
||||
|
||||
#if ANY_BUTTON(EN1, EN2, ENC, BACK)
|
||||
|
||||
uint8_t newbutton = 0;
|
||||
|
||||
#if BUTTON_EXISTS(EN1)
|
||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
||||
#endif
|
||||
#if BUTTON_EXISTS(EN2)
|
||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
||||
#endif
|
||||
#if BUTTON_EXISTS(ENC)
|
||||
if (BUTTON_PRESSED(ENC)) newbutton |= EN_C;
|
||||
#endif
|
||||
#if BUTTON_EXISTS(BACK)
|
||||
if (BUTTON_PRESSED(BACK)) newbutton |= EN_D;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
constexpr uint8_t newbutton = 0;
|
||||
|
||||
#endif
|
||||
|
||||
static uint8_t buttons = 0;
|
||||
buttons = newbutton;
|
||||
static uint8_t lastEncoderBits;
|
||||
|
||||
#define encrot0 0
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
//#define GRAPHICAL_TFT_ROTATE_180
|
||||
//#define TFT_ROTATION TFT_ROTATE_180
|
||||
#define USE_WIFI_FUNCTION 0
|
||||
|
||||
extern void tft_lvgl_init();
|
||||
|
@@ -110,24 +110,17 @@ const char *resultMessages[] = {
|
||||
// 230400b always manages to connect.
|
||||
static const uint32_t uploadBaudRates[] = { 460800, 230400, 115200, 74880 };
|
||||
|
||||
|
||||
|
||||
signed char IsReady() {
|
||||
return esp_upload.state == upload_idle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void uploadPort_write(const uint8_t *buf, size_t len) {
|
||||
#if 0
|
||||
int i;
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
|
||||
|
||||
USART_SendData(USART1, *(buf + i));
|
||||
for (i = 0; i < len; i++) {
|
||||
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { /* nada */ }
|
||||
USART_SendData(USART1, *(buf + i));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -138,28 +131,22 @@ char uploadPort_read() {
|
||||
return retChar;
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int uploadPort_available() {
|
||||
return usartFifoAvailable(&WifiRxFifo);
|
||||
}
|
||||
|
||||
|
||||
void uploadPort_begin() {
|
||||
esp_port_begin(1);
|
||||
}
|
||||
|
||||
void uploadPort_close() {
|
||||
|
||||
//WIFI_COM.end();
|
||||
//WIFI_COM.begin(115200, true);
|
||||
|
||||
esp_port_begin(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void flushInput() {
|
||||
while (uploadPort_available() != 0) {
|
||||
(void)uploadPort_read();
|
||||
@@ -304,7 +291,6 @@ EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t
|
||||
|
||||
*bodyLen = 0;
|
||||
|
||||
|
||||
while (state != done) {
|
||||
uint8_t c;
|
||||
EspUploadResult stat;
|
||||
@@ -322,73 +308,73 @@ EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t
|
||||
}
|
||||
|
||||
// sufficient bytes have been received for the current state, process them
|
||||
switch(state) {
|
||||
case begin: // expecting frame start
|
||||
c = uploadPort_read();
|
||||
if (c != (uint8_t)0xC0) {
|
||||
break;
|
||||
}
|
||||
state = header;
|
||||
needBytes = 2;
|
||||
|
||||
break;
|
||||
case end: // expecting frame end
|
||||
c = uploadPort_read();
|
||||
if (c != (uint8_t)0xC0) {
|
||||
return slipFrame;
|
||||
}
|
||||
state = done;
|
||||
|
||||
break;
|
||||
|
||||
case header: // reading an 8-byte header
|
||||
case body: // reading the response body
|
||||
{
|
||||
int rslt;
|
||||
// retrieve a byte with SLIP decoding
|
||||
rslt = ReadByte(&c, 1);
|
||||
if (rslt != 1 && rslt != 2) {
|
||||
// some error occurred
|
||||
stat = (rslt == 0 || rslt == -2) ? slipData : slipFrame;
|
||||
return stat;
|
||||
switch (state) {
|
||||
case begin: // expecting frame start
|
||||
c = uploadPort_read();
|
||||
if (c != (uint8_t)0xC0) {
|
||||
break;
|
||||
}
|
||||
else if (state == header) {
|
||||
//store the header byte
|
||||
hdr[hdrIdx++] = c;
|
||||
if (hdrIdx >= headerLength) {
|
||||
// get the body length, prepare a buffer for it
|
||||
*bodyLen = (uint16_t)getData(2, hdr, 2);
|
||||
state = header;
|
||||
needBytes = 2;
|
||||
|
||||
// extract the value, if requested
|
||||
if (valp != 0) {
|
||||
*valp = getData(4, hdr, 4);
|
||||
}
|
||||
break;
|
||||
case end: // expecting frame end
|
||||
c = uploadPort_read();
|
||||
if (c != (uint8_t)0xC0) {
|
||||
return slipFrame;
|
||||
}
|
||||
state = done;
|
||||
|
||||
if (*bodyLen != 0) {
|
||||
state = body;
|
||||
break;
|
||||
|
||||
case header: // reading an 8-byte header
|
||||
case body: // reading the response body
|
||||
{
|
||||
int rslt;
|
||||
// retrieve a byte with SLIP decoding
|
||||
rslt = ReadByte(&c, 1);
|
||||
if (rslt != 1 && rslt != 2) {
|
||||
// some error occurred
|
||||
stat = (rslt == 0 || rslt == -2) ? slipData : slipFrame;
|
||||
return stat;
|
||||
}
|
||||
else if (state == header) {
|
||||
//store the header byte
|
||||
hdr[hdrIdx++] = c;
|
||||
if (hdrIdx >= headerLength) {
|
||||
// get the body length, prepare a buffer for it
|
||||
*bodyLen = (uint16_t)getData(2, hdr, 2);
|
||||
|
||||
// extract the value, if requested
|
||||
if (valp != 0) {
|
||||
*valp = getData(4, hdr, 4);
|
||||
}
|
||||
|
||||
if (*bodyLen != 0) {
|
||||
state = body;
|
||||
}
|
||||
else {
|
||||
needBytes = 1;
|
||||
state = end;
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
// Store the response body byte, check for completion
|
||||
if (bodyIdx < ARRAY_SIZE(respBuf)) {
|
||||
respBuf[bodyIdx] = c;
|
||||
}
|
||||
++bodyIdx;
|
||||
if (bodyIdx >= *bodyLen) {
|
||||
needBytes = 1;
|
||||
state = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Store the response body byte, check for completion
|
||||
if (bodyIdx < ARRAY_SIZE(respBuf)) {
|
||||
respBuf[bodyIdx] = c;
|
||||
}
|
||||
++bodyIdx;
|
||||
if (bodyIdx >= *bodyLen) {
|
||||
needBytes = 1;
|
||||
state = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default: // this shouldn't happen
|
||||
return slipState;
|
||||
default: // this shouldn't happen
|
||||
return slipState;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +383,7 @@ EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t
|
||||
opRet = (uint8_t)getData(1, hdr, 1);
|
||||
// Sync packets often provoke a response with a zero opcode instead of ESP_SYNC
|
||||
if (resp != 0x01 || opRet != op) {
|
||||
//debug//printf("resp %02x %02x\n", resp, opRet);
|
||||
//printf("resp %02x %02x\n", resp, opRet); //debug
|
||||
return respHeader;
|
||||
}
|
||||
|
||||
@@ -432,20 +418,19 @@ void _writePacket(const uint8_t *data, size_t len) {
|
||||
// 0xC0 and 0xDB replaced by the two-byte sequences {0xDB, 0xDC} and {0xDB, 0xDD} respectively.
|
||||
|
||||
void writePacket(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen) {
|
||||
|
||||
WriteByteRaw(0xC0); // send the packet start character
|
||||
WriteByteRaw(0xC0); // send the packet start character
|
||||
_writePacket(hdr, hdrLen); // send the header
|
||||
_writePacket(data, dataLen); // send the data block
|
||||
WriteByteRaw(0xC0); // send the packet end character
|
||||
_writePacket(data, dataLen); // send the data block
|
||||
WriteByteRaw(0xC0); // send the packet end character
|
||||
}
|
||||
|
||||
// Send a packet to the serial port while performing SLIP framing. The packet data comprises a header and an optional data block.
|
||||
// This is like writePacket except that it does a fast block write for both the header and the main data with no SLIP encoding. Used to send sync commands.
|
||||
void writePacketRaw(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen) {
|
||||
WriteByteRaw(0xC0); // send the packet start character
|
||||
_writePacketRaw(hdr, hdrLen); // send the header
|
||||
WriteByteRaw(0xC0); // send the packet start character
|
||||
_writePacketRaw(hdr, hdrLen); // send the header
|
||||
_writePacketRaw(data, dataLen); // send the data block in raw mode
|
||||
WriteByteRaw(0xC0); // send the packet end character
|
||||
WriteByteRaw(0xC0); // send the packet end character
|
||||
}
|
||||
|
||||
// Send a command to the attached device together with the supplied data, if any.
|
||||
@@ -460,12 +445,10 @@ void sendCommand(uint8_t op, uint32_t checkVal, const uint8_t *data, size_t data
|
||||
|
||||
// send the packet
|
||||
//flushInput();
|
||||
if (op == ESP_SYNC) {
|
||||
if (op == ESP_SYNC)
|
||||
writePacketRaw(hdr, sizeof(hdr), data, dataLen);
|
||||
}
|
||||
else {
|
||||
else
|
||||
writePacket(hdr, sizeof(hdr), data, dataLen);
|
||||
}
|
||||
}
|
||||
|
||||
// Send a command to the attached device together with the supplied data, if any, and get the response
|
||||
@@ -476,9 +459,8 @@ EspUploadResult doCommand(uint8_t op, const uint8_t *data, size_t dataLen, uint3
|
||||
sendCommand(op, checkVal, data, dataLen);
|
||||
|
||||
stat = readPacket(op, valp, &bodyLen, msTimeout);
|
||||
if (stat == success && bodyLen != 2) {
|
||||
if (stat == success && bodyLen != 2)
|
||||
stat = badReply;
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
@@ -611,6 +593,8 @@ EspUploadResult flashWriteBlock(uint16_t flashParmVal, uint16_t flashParmMask) {
|
||||
//printf("Upload %d\%\n", ftell(&esp_upload.uploadFile) * 100 / esp_upload.fileSize);
|
||||
|
||||
return stat;
|
||||
#else
|
||||
return success;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -625,15 +609,14 @@ void upload_spin() {
|
||||
esp_upload.uploadResult = connected;
|
||||
esp_upload.state = done;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
|
||||
// Reset the serial port at the new baud rate. Also reset the ESP8266.
|
||||
// const uint32_t baud = uploadBaudRates[esp_upload.connectAttemptNumber/esp_upload.retriesPerBaudRate];
|
||||
// const uint32_t baud = uploadBaudRates[esp_upload.connectAttemptNumber/esp_upload.retriesPerBaudRate];
|
||||
if (esp_upload.connectAttemptNumber % esp_upload.retriesPerBaudRate == 0) {
|
||||
}
|
||||
// uploadPort.begin(baud);
|
||||
// uploadPort_close();
|
||||
|
||||
//uploadPort.begin(baud);
|
||||
//uploadPort_close();
|
||||
|
||||
uploadPort_begin();
|
||||
|
||||
@@ -654,7 +637,7 @@ void upload_spin() {
|
||||
esp_upload.lastAttemptTime = getWifiTick();
|
||||
if (res == success) {
|
||||
// Successful connection
|
||||
// //MessageF(" success on attempt %d\n", (connectAttemptNumber % retriesPerBaudRate) + 1);
|
||||
//MessageF(" success on attempt %d\n", (connectAttemptNumber % retriesPerBaudRate) + 1);
|
||||
//printf("connect success\n");
|
||||
esp_upload.state = erasing;
|
||||
}
|
||||
@@ -675,14 +658,13 @@ void upload_spin() {
|
||||
const uint32_t sectorSize = 4096;
|
||||
const uint32_t numSectors = (esp_upload.fileSize + sectorSize - 1)/sectorSize;
|
||||
const uint32_t startSector = esp_upload.uploadAddress/sectorSize;
|
||||
uint32_t headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
|
||||
|
||||
if (numSectors < headSectors) {
|
||||
headSectors = numSectors;
|
||||
}
|
||||
eraseSize = (numSectors < 2 * headSectors)
|
||||
? (numSectors + 1) / 2 * sectorSize
|
||||
: (numSectors - headSectors) * sectorSize;
|
||||
uint32_t headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
|
||||
NOMORE(headSectors, numSectors);
|
||||
|
||||
eraseSize = (numSectors < 2 * headSectors)
|
||||
? (numSectors + 1) / 2 * sectorSize
|
||||
: (numSectors - headSectors) * sectorSize;
|
||||
|
||||
//MessageF("Erasing %u bytes...\n", fileSize);
|
||||
esp_upload.uploadResult = flashBegin(esp_upload.uploadAddress, eraseSize);
|
||||
@@ -755,7 +737,7 @@ void SendUpdateFile(const char *file, uint32_t address) {
|
||||
|
||||
if (res != FR_OK) return;
|
||||
|
||||
esp_upload.fileSize = f_size(&esp_upload.uploadFile);
|
||||
esp_upload.fileSize = f_size(&esp_upload.uploadFile);
|
||||
if (esp_upload.fileSize == 0) {
|
||||
f_close(&esp_upload.uploadFile);
|
||||
return;
|
||||
|
@@ -305,27 +305,9 @@ namespace ExtUI {
|
||||
}
|
||||
|
||||
void setAxisPosition_mm(const float position, const axis_t axis, const feedRate_t feedrate/*=0*/) {
|
||||
// Start with no limits to movement
|
||||
float min = current_position[axis] - 1000,
|
||||
max = current_position[axis] + 1000;
|
||||
|
||||
// Limit to software endstops, if enabled
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
if (soft_endstops_enabled) switch (axis) {
|
||||
case X_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_X, min = soft_endstop.min.x);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_X, max = soft_endstop.max.x);
|
||||
break;
|
||||
case Y_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_Y, min = soft_endstop.min.y);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_Y, max = soft_endstop.max.y);
|
||||
break;
|
||||
case Z_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_Z, min = soft_endstop.min.z);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_Z, max = soft_endstop.max.z);
|
||||
default: break;
|
||||
}
|
||||
#endif // HAS_SOFTWARE_ENDSTOPS
|
||||
// Get motion limit from software endstops, if any
|
||||
float min, max;
|
||||
soft_endstop.get_manual_axis_limits((AxisEnum)axis, min, max);
|
||||
|
||||
// Delta limits XY based on the current offset from center
|
||||
// This assumes the center is 0,0
|
||||
@@ -389,8 +371,8 @@ namespace ExtUI {
|
||||
}
|
||||
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
bool getSoftEndstopState() { return soft_endstops_enabled; }
|
||||
void setSoftEndstopState(const bool value) { soft_endstops_enabled = value; }
|
||||
bool getSoftEndstopState() { return soft_endstop._enabled; }
|
||||
void setSoftEndstopState(const bool value) { soft_endstop._enabled = value; }
|
||||
#endif
|
||||
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
|
@@ -67,6 +67,9 @@ namespace Language_en {
|
||||
PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home Z");
|
||||
PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Auto Z-Align");
|
||||
PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Assisted Tramming");
|
||||
PROGMEM Language_Str MSG_ITERATION = _UxGT("G34 Iteration: %i");
|
||||
PROGMEM Language_Str MSG_DECREASING_ACCURACY = _UxGT("Accuracy Decreasing!");
|
||||
PROGMEM Language_Str MSG_ACCURACY_ACHIEVED = _UxGT("Accuracy Achieved");
|
||||
PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Homing XYZ");
|
||||
PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Click to Begin");
|
||||
PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Next Point");
|
||||
|
@@ -58,16 +58,16 @@
|
||||
void menu_tmc();
|
||||
void menu_backlash();
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
|
||||
#include "../../feature/dac/stepper_dac.h"
|
||||
|
||||
void menu_dac() {
|
||||
static xyze_uint8_t driverPercent;
|
||||
LOOP_XYZE(i) driverPercent[i] = dac_current_get_percent((AxisEnum)i);
|
||||
LOOP_XYZE(i) driverPercent[i] = stepper_dac.get_current_percent((AxisEnum)i);
|
||||
START_MENU();
|
||||
BACK_ITEM(MSG_ADVANCED_SETTINGS);
|
||||
#define EDIT_DAC_PERCENT(A) EDIT_ITEM(uint8, MSG_DAC_PERCENT_##A, &driverPercent[_AXIS(A)], 0, 100, []{ dac_current_set_percents(driverPercent); })
|
||||
#define EDIT_DAC_PERCENT(A) EDIT_ITEM(uint8, MSG_DAC_PERCENT_##A, &driverPercent[_AXIS(A)], 0, 100, []{ stepper_dac.set_current_percents(driverPercent); })
|
||||
EDIT_DAC_PERCENT(X);
|
||||
EDIT_DAC_PERCENT(Y);
|
||||
EDIT_DAC_PERCENT(Z);
|
||||
@@ -568,7 +568,7 @@ void menu_advanced_settings() {
|
||||
SUBMENU(MSG_BACKLASH, menu_backlash);
|
||||
#endif
|
||||
|
||||
#if ENABLED(DAC_STEPPER_CURRENT)
|
||||
#if ENABLED(HAS_MOTOR_CURRENT_DAC)
|
||||
SUBMENU(MSG_DRIVE_STRENGTH, menu_dac);
|
||||
#endif
|
||||
#if HAS_MOTOR_CURRENT_PWM
|
||||
|
@@ -118,7 +118,7 @@ void lcd_delta_settings() {
|
||||
}
|
||||
|
||||
void menu_delta_calibrate() {
|
||||
const bool all_homed = all_axes_homed();
|
||||
TERN_(DELTA_CALIBRATION_MENU, const bool all_homed = all_axes_homed()); // Acquire ahead of loop
|
||||
|
||||
START_MENU();
|
||||
BACK_ITEM(MSG_MAIN);
|
||||
|
@@ -57,28 +57,9 @@
|
||||
static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) {
|
||||
if (ui.use_click()) return ui.goto_previous_screen_no_defer();
|
||||
if (ui.encoderPosition && !ui.manual_move.processing) {
|
||||
|
||||
// Start with no limits to movement
|
||||
float min = current_position[axis] - 1000,
|
||||
max = current_position[axis] + 1000;
|
||||
|
||||
// Limit to software endstops, if enabled
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
if (soft_endstops_enabled) switch (axis) {
|
||||
case X_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_X, min = soft_endstop.min.x);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_X, max = soft_endstop.max.x);
|
||||
break;
|
||||
case Y_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_Y, min = soft_endstop.min.y);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_Y, max = soft_endstop.max.y);
|
||||
break;
|
||||
case Z_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_Z, min = soft_endstop.min.z);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_Z, max = soft_endstop.max.z);
|
||||
default: break;
|
||||
}
|
||||
#endif // HAS_SOFTWARE_ENDSTOPS
|
||||
// Get motion limit from software endstops, if any
|
||||
float min, max;
|
||||
soft_endstop.get_manual_axis_limits(axis, min, max);
|
||||
|
||||
// Delta limits XY based on the current offset from center
|
||||
// This assumes the center is 0,0
|
||||
@@ -238,7 +219,7 @@ void menu_move() {
|
||||
BACK_ITEM(MSG_MOTION);
|
||||
|
||||
#if BOTH(HAS_SOFTWARE_ENDSTOPS, SOFT_ENDSTOPS_MENU_ITEM)
|
||||
EDIT_ITEM(bool, MSG_LCD_SOFT_ENDSTOPS, &soft_endstops_enabled);
|
||||
EDIT_ITEM(bool, MSG_LCD_SOFT_ENDSTOPS, &soft_endstop._enabled);
|
||||
#endif
|
||||
|
||||
if (NONE(IS_KINEMATIC, NO_MOTION_BEFORE_HOMING) || all_axes_homed()) {
|
||||
@@ -358,7 +339,7 @@ void menu_motion() {
|
||||
//
|
||||
// Auto Z-Align
|
||||
//
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
#if EITHER(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION)
|
||||
GCODES_ITEM(MSG_AUTO_Z_ALIGN, PSTR("G34"));
|
||||
#endif
|
||||
|
||||
|
@@ -48,16 +48,12 @@
|
||||
float z_offset_backup, calculated_z_offset;
|
||||
|
||||
TERN_(HAS_LEVELING, bool leveling_was_active);
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, bool store_soft_endstops_enabled);
|
||||
|
||||
void prepare_for_calibration() {
|
||||
z_offset_backup = probe.offset.z;
|
||||
|
||||
// Disable soft endstops for free Z movement
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
store_soft_endstops_enabled = soft_endstops_enabled;
|
||||
soft_endstops_enabled = false;
|
||||
#endif
|
||||
SET_SOFT_ENDSTOP_LOOSE(true);
|
||||
|
||||
// Disable leveling for raw planner motion
|
||||
#if HAS_LEVELING
|
||||
@@ -68,7 +64,7 @@ void prepare_for_calibration() {
|
||||
|
||||
void set_offset_and_go_back(const float &z) {
|
||||
probe.offset.z = z;
|
||||
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = store_soft_endstops_enabled);
|
||||
SET_SOFT_ENDSTOP_LOOSE(false);
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(leveling_was_active));
|
||||
ui.goto_previous_screen_no_defer();
|
||||
}
|
||||
|
@@ -188,11 +188,10 @@ void _lcd_ubl_edit_mesh() {
|
||||
*/
|
||||
void _lcd_ubl_validate_custom_mesh() {
|
||||
char ubl_lcd_gcode[24];
|
||||
const int16_t temp = TERN(HAS_HEATED_BED, custom_bed_temp, 0);
|
||||
sprintf_P(ubl_lcd_gcode, PSTR("G28\nG26 C P H%" PRIi16 TERN_(HAS_HEATED_BED, " B%" PRIi16))
|
||||
, custom_hotend_temp
|
||||
#if HAS_HEATED_BED
|
||||
, temp
|
||||
, custom_bed_temp
|
||||
#endif
|
||||
);
|
||||
queue.inject(ubl_lcd_gcode);
|
||||
|
@@ -43,8 +43,13 @@
|
||||
#endif
|
||||
|
||||
#ifndef TFT_PIXEL_OFFSET_X
|
||||
#define TFT_PIXEL_OFFSET_X 48
|
||||
#if GRAPHICAL_TFT_UPSCALE == 2
|
||||
#define TFT_PIXEL_OFFSET_X 32
|
||||
#else
|
||||
#define TFT_PIXEL_OFFSET_X 48
|
||||
#endif
|
||||
#endif
|
||||
#ifndef TFT_PIXEL_OFFSET_Y
|
||||
#define TFT_PIXEL_OFFSET_Y 48
|
||||
// 32 is better for both 320x240 and 480x320
|
||||
#define TFT_PIXEL_OFFSET_Y 32
|
||||
#endif
|
||||
|
@@ -25,173 +25,16 @@
|
||||
#if HAS_GRAPHICAL_TFT
|
||||
|
||||
#include "tft.h"
|
||||
#include "st7735.h"
|
||||
#include "st7789v.h"
|
||||
#include "st7796s.h"
|
||||
#include "r65105.h"
|
||||
#include "ili9328.h"
|
||||
#include "ili9341.h"
|
||||
#include "ili9488.h"
|
||||
|
||||
//#define DEBUG_GRAPHICAL_TFT
|
||||
#define DEBUG_OUT ENABLED(DEBUG_GRAPHICAL_TFT)
|
||||
#include "../../core/debug_out.h"
|
||||
|
||||
uint16_t TFT::buffer[];
|
||||
uint32_t TFT::lcd_id = 0xFFFFFFFF;
|
||||
|
||||
void TFT::init() {
|
||||
if (lcd_id != 0xFFFFFFFF) return;
|
||||
|
||||
io.Init();
|
||||
|
||||
#if TFT_DRIVER != AUTO
|
||||
lcd_id = TFT_DRIVER;
|
||||
#endif
|
||||
|
||||
#if TFT_DRIVER == ST7735
|
||||
write_esc_sequence(st7735_init);
|
||||
#elif TFT_DRIVER == ST7789
|
||||
write_esc_sequence(st7789v_init);
|
||||
#elif TFT_DRIVER == ST7796
|
||||
write_esc_sequence(st7796s_init);
|
||||
#elif TFT_DRIVER == R61505
|
||||
write_esc_sequence(r61505_init);
|
||||
#elif TFT_DRIVER == ILI9328
|
||||
write_esc_sequence(ili9328_init);
|
||||
#elif TFT_DRIVER == ILI9341
|
||||
write_esc_sequence(ili9341_init);
|
||||
#elif TFT_DRIVER == ILI9488
|
||||
write_esc_sequence(ili9488_init);
|
||||
#elif TFT_DRIVER == LERDGE_ST7796
|
||||
lcd_id = ST7796;
|
||||
write_esc_sequence(lerdge_st7796s_init);
|
||||
|
||||
#elif TFT_DRIVER == AUTO // autodetect
|
||||
|
||||
lcd_id = io.GetID() & 0xFFFF;
|
||||
|
||||
switch (lcd_id) {
|
||||
case ST7796: // ST7796S 480x320
|
||||
DEBUG_ECHO_MSG(" ST7796S");
|
||||
write_esc_sequence(st7796s_init);
|
||||
break;
|
||||
case ST7789: // ST7789V 320x240
|
||||
DEBUG_ECHO_MSG(" ST7789V");
|
||||
write_esc_sequence(st7789v_init);
|
||||
break;
|
||||
case ST7735: // ST7735 160x128
|
||||
DEBUG_ECHO_MSG(" ST7735");
|
||||
write_esc_sequence(st7735_init);
|
||||
break;
|
||||
case R61505: // R61505U 320x240
|
||||
DEBUG_ECHO_MSG(" R61505U");
|
||||
write_esc_sequence(r61505_init);
|
||||
break;
|
||||
case ILI9328: // ILI9328 320x240
|
||||
DEBUG_ECHO_MSG(" ILI9328");
|
||||
write_esc_sequence(ili9328_init);
|
||||
break;
|
||||
case ILI9341: // ILI9341 320x240
|
||||
DEBUG_ECHO_MSG(" ILI9341");
|
||||
write_esc_sequence(ili9341_init);
|
||||
break;
|
||||
case ILI9488: // ILI9488 480x320
|
||||
DEBUG_ECHO_MSG(" ILI9488");
|
||||
write_esc_sequence(ili9488_init);
|
||||
break;
|
||||
default:
|
||||
lcd_id = 0;
|
||||
}
|
||||
#else
|
||||
#error Unsupported TFT driver
|
||||
#endif
|
||||
}
|
||||
|
||||
void TFT::set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
|
||||
#ifdef OFFSET_X
|
||||
Xmin += OFFSET_X; Xmax += OFFSET_X;
|
||||
#endif
|
||||
#ifdef OFFSET_Y
|
||||
Ymin += OFFSET_Y; Ymax += OFFSET_Y;
|
||||
#endif
|
||||
|
||||
switch (lcd_id) {
|
||||
case ST7735: // ST7735 160x128
|
||||
case ST7789: // ST7789V 320x240
|
||||
case ST7796: // ST7796 480x320
|
||||
case ILI9341: // ILI9341 320x240
|
||||
case ILI9488: // ILI9488 480x320
|
||||
io.DataTransferBegin(DATASIZE_8BIT);
|
||||
|
||||
// CASET: Column Address Set
|
||||
io.WriteReg(ILI9341_CASET);
|
||||
io.WriteData((Xmin >> 8) & 0xFF);
|
||||
io.WriteData(Xmin & 0xFF);
|
||||
io.WriteData((Xmax >> 8) & 0xFF);
|
||||
io.WriteData(Xmax & 0xFF);
|
||||
|
||||
// RASET: Row Address Set
|
||||
io.WriteReg(ILI9341_PASET);
|
||||
io.WriteData((Ymin >> 8) & 0xFF);
|
||||
io.WriteData(Ymin & 0xFF);
|
||||
io.WriteData((Ymax >> 8) & 0xFF);
|
||||
io.WriteData(Ymax & 0xFF);
|
||||
|
||||
// RAMWR: Memory Write
|
||||
io.WriteReg(ILI9341_RAMWR);
|
||||
break;
|
||||
case R61505: // R61505U 320x240
|
||||
case ILI9328: // ILI9328 320x240
|
||||
io.DataTransferBegin(DATASIZE_16BIT);
|
||||
|
||||
// Mind the mess: with landscape screen orientation 'Horizontal' is Y and 'Vertical' is X
|
||||
io.WriteReg(ILI9328_HASTART);
|
||||
io.WriteData(Ymin);
|
||||
io.WriteReg(ILI9328_HAEND);
|
||||
io.WriteData(Ymax);
|
||||
io.WriteReg(ILI9328_VASTART);
|
||||
io.WriteData(Xmin);
|
||||
io.WriteReg(ILI9328_VAEND);
|
||||
io.WriteData(Xmax);
|
||||
|
||||
io.WriteReg(ILI9328_HASET);
|
||||
io.WriteData(Ymin);
|
||||
io.WriteReg(ILI9328_VASET);
|
||||
io.WriteData(Xmin);
|
||||
|
||||
io.WriteReg(ILI9328_RAMWR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
io.DataTransferEnd();
|
||||
}
|
||||
|
||||
void TFT::write_esc_sequence(const uint16_t *Sequence) {
|
||||
uint16_t dataWidth, data;
|
||||
|
||||
dataWidth = *Sequence++;
|
||||
io.DataTransferBegin(dataWidth);
|
||||
|
||||
for (;;) {
|
||||
data = *Sequence++;
|
||||
if (data != 0xFFFF) {
|
||||
io.WriteData(data);
|
||||
continue;
|
||||
}
|
||||
data = *Sequence++;
|
||||
if (data == 0x7FFF) return;
|
||||
if (data == 0xFFFF)
|
||||
io.WriteData(0xFFFF);
|
||||
else if (data & 0x8000)
|
||||
delay(data & 0x7FFF);
|
||||
else if ((data & 0xFF00) == 0)
|
||||
io.WriteReg(data);
|
||||
}
|
||||
|
||||
io.DataTransferEnd();
|
||||
io.InitTFT();
|
||||
}
|
||||
|
||||
TFT tft;
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include "tft_color.h"
|
||||
#include "tft_string.h"
|
||||
#include "tft_image.h"
|
||||
#include "tft_io.h"
|
||||
#include "../tft_io/tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -40,20 +40,6 @@
|
||||
#error "Unsupported display resolution!"
|
||||
#endif
|
||||
|
||||
#define ST7735 0x89F0
|
||||
#define ST7789 0x8552
|
||||
#define ST7796 0x7796
|
||||
#define R61505 0x1505
|
||||
#define ILI9328 0x9328
|
||||
#define ILI9341 0x9341
|
||||
#define ILI9488 0x9488
|
||||
#define LERDGE_ST7796 0xFFFE
|
||||
#define AUTO 0xFFFF
|
||||
|
||||
#ifndef TFT_DRIVER
|
||||
#define TFT_DRIVER AUTO
|
||||
#endif
|
||||
|
||||
#ifndef TFT_BUFFER_SIZE
|
||||
#ifdef STM32F103xB
|
||||
#define TFT_BUFFER_SIZE 1024
|
||||
@@ -71,14 +57,8 @@
|
||||
#error "TFT_BUFFER_SIZE can not exceed 65535"
|
||||
#endif
|
||||
|
||||
#define ESC_REG(x) 0xFFFF, 0x00FF & (uint16_t)x
|
||||
#define ESC_DELAY(x) 0xFFFF, 0x8000 | (x & 0x7FFF)
|
||||
#define ESC_END 0xFFFF, 0x7FFF
|
||||
#define ESC_FFFF 0xFFFF, 0xFFFF
|
||||
|
||||
class TFT {
|
||||
private:
|
||||
static uint32_t lcd_id;
|
||||
static TFT_String string;
|
||||
static TFT_IO io;
|
||||
|
||||
@@ -91,13 +71,11 @@ class TFT {
|
||||
static inline void set_font(const uint8_t *Font) { string.set_font(Font); }
|
||||
static inline void add_glyphs(const uint8_t *Font) { string.add_glyphs(Font); }
|
||||
|
||||
static void set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax);
|
||||
static void write_esc_sequence(const uint16_t *Sequence);
|
||||
|
||||
static inline bool is_busy() { return io.isBusy(); }
|
||||
static inline void abort() { io.Abort(); }
|
||||
static inline void write_multiple(uint16_t Data, uint16_t Count) { io.WriteMultiple(Data, Count); }
|
||||
static inline void write_sequence(uint16_t *Data, uint16_t Count) { io.WriteSequence(Data, Count); }
|
||||
static inline void set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) { io.set_window(Xmin, Ymin, Xmax, Ymax); }
|
||||
|
||||
static inline void fill(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { queue.fill(x, y, width, height, color); }
|
||||
static inline void canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { queue.canvas(x, y, width, height); }
|
||||
|
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_SPI_TFT
|
||||
#include HAL_PATH(../../HAL, tft/tft_spi.h)
|
||||
#elif HAS_FSMC_TFT
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
#endif
|
@@ -116,6 +116,17 @@ void TFT_String::add(uint8_t *string, int8_t index, uint8_t *itemString) {
|
||||
eol();
|
||||
}
|
||||
|
||||
void TFT_String::add(uint8_t *string) {
|
||||
wchar_t wchar;
|
||||
while (*string) {
|
||||
string = get_utf8_value_cb(string, read_byte, &wchar);
|
||||
if (wchar > 255) wchar |= 0x0080;
|
||||
uint8_t ch = uint8_t(wchar & 0x00FF);
|
||||
add_character(ch);
|
||||
}
|
||||
eol();
|
||||
}
|
||||
|
||||
void TFT_String::add_character(uint8_t character) {
|
||||
if (length < MAX_STRING_LENGTH) {
|
||||
data[length] = character;
|
||||
|
@@ -85,7 +85,7 @@ class TFT_String {
|
||||
|
||||
static void set();
|
||||
static void add(uint8_t character) { add_character(character); eol(); }
|
||||
static void add(uint8_t *string) { while (*string) { add_character(*string++); } eol(); }
|
||||
static void add(uint8_t *string);
|
||||
static void add(uint8_t *string, int8_t index, uint8_t *itemString = NULL);
|
||||
static void set(uint8_t *string) { set(); add(string); };
|
||||
static void set(uint8_t *string, int8_t index, const char *itemString = NULL) { set(); add(string, index, (uint8_t *)itemString); };
|
||||
|
@@ -50,6 +50,9 @@ touch_calibration_t Touch::calibration;
|
||||
calibrationState Touch::calibration_state = CALIBRATION_NONE;
|
||||
touch_calibration_point_t Touch::calibration_points[4];
|
||||
#endif
|
||||
#if HAS_RESUME_CONTINUE
|
||||
extern bool wait_for_user;
|
||||
#endif
|
||||
|
||||
void Touch::init() {
|
||||
calibration_reset();
|
||||
@@ -80,6 +83,15 @@ void Touch::idle() {
|
||||
now = millis();
|
||||
|
||||
if (get_point(&_x, &_y)) {
|
||||
#if HAS_RESUME_CONTINUE
|
||||
// UI is waiting for a click anywhere?
|
||||
if (wait_for_user) {
|
||||
touch_control_type = CLICK;
|
||||
ui.lcd_clicked = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LCD_TIMEOUT_TO_STATUS
|
||||
ui.return_to_status_ms = now + LCD_TIMEOUT_TO_STATUS;
|
||||
#endif
|
||||
|
@@ -813,27 +813,9 @@ static void moveAxis(AxisEnum axis, const int8_t direction) {
|
||||
}
|
||||
|
||||
if (!ui.manual_move.processing) {
|
||||
// Start with no limits to movement
|
||||
float min = current_position[axis] - 1000,
|
||||
max = current_position[axis] + 1000;
|
||||
|
||||
// Limit to software endstops, if enabled
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
if (soft_endstops_enabled) switch (axis) {
|
||||
case X_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_X, min = soft_endstop.min.x);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_X, max = soft_endstop.max.x);
|
||||
break;
|
||||
case Y_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_Y, min = soft_endstop.min.y);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_Y, max = soft_endstop.max.y);
|
||||
break;
|
||||
case Z_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_Z, min = soft_endstop.min.z);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_Z, max = soft_endstop.max.z);
|
||||
default: break;
|
||||
}
|
||||
#endif // HAS_SOFTWARE_ENDSTOPS
|
||||
// Get motion limit from software endstops, if any
|
||||
float min, max;
|
||||
soft_endstop.get_manual_axis_limits(axis, min, max);
|
||||
|
||||
// Delta limits XY based on the current offset from center
|
||||
// This assumes the center is 0,0
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft.h"
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -40,8 +40,31 @@
|
||||
#define ILI9328_ETMOD_AM 0x0008 // 0 - Horizontal / 1 - Vertical
|
||||
|
||||
// MKS Robin TFT v1.1 - 320x240 ; Cable on the left side
|
||||
#define ILI9328_DRVCTL_DATA ILI9328_DRVCTL_SS
|
||||
#define ILI9328_ETMOD_DATA ILI9328_ETMOD_BGR | ILI9328_ETMOD_ID1 | ILI9328_ETMOD_ID0 | ILI9328_ETMOD_AM
|
||||
|
||||
#if TFT_ROTATION == TFT_ROTATE_180
|
||||
#define ILI9328_DRVCTL_DATA 0x0000
|
||||
#define ILI9328_GATE_SCANCTL1_DATA 0xA700
|
||||
#else
|
||||
#define ILI9328_DRVCTL_DATA ILI9328_DRVCTL_SS
|
||||
#define ILI9328_GATE_SCANCTL1_DATA 0x2700
|
||||
#endif
|
||||
|
||||
/*
|
||||
#define ILI9328_ETMOD_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9328_ETMOD_AM) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ILI9328_ETMOD_ID1) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ILI9328_ETMOD_ID0)
|
||||
*/
|
||||
|
||||
#define ILI9328_ETMOD_ORIENTATION (ILI9328_ETMOD_AM | ILI9328_ETMOD_ID1 | ILI9328_ETMOD_ID0)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR
|
||||
#define ILI9328_ETMOD_COLOR ILI9328_ETMOD_BGR
|
||||
#elif TFT_COLOR == TFT_COLOR_RGB
|
||||
#define ILI9328_ETMOD_COLOR ILI9328_ETMOD_RGB
|
||||
#endif
|
||||
|
||||
#define ILI9328_ETMOD_DATA (ILI9328_ETMOD_ORIENTATION) | (ILI9328_ETMOD_COLOR)
|
||||
|
||||
|
||||
#define ILI9328_RDDID 0x00 // ID code - 0x9328
|
||||
#define ILI9328_DRVCTL 0x01 // Driver Output Control
|
||||
@@ -134,7 +157,7 @@ static const uint16_t ili9328_init[] = {
|
||||
ESC_REG(ILI9328_PWCTRL7), 0x0004,
|
||||
ESC_REG(ILI9328_FRMCTR), 0x000D,
|
||||
ESC_DELAY(50),
|
||||
ESC_REG(ILI9328_GATE_SCANCTL1), 0x2700,
|
||||
ESC_REG(ILI9328_GATE_SCANCTL1), ILI9328_GATE_SCANCTL1_DATA,
|
||||
ESC_REG(ILI9328_GATE_SCANCTL2), 0x0001,
|
||||
ESC_REG(ILI9328_GATE_SCANCTL3), 0x0000,
|
||||
ESC_REG(ILI9328_PLTPOS1), 0x0000,
|
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft.h"
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -38,13 +38,17 @@
|
||||
#define ILI9341_ORIENTATION_LEFT ILI9341_MADCTL_MY | ILI9341_MADCTL_MX | ILI9341_MADCTL_MV // 320x240 ; Cable on the left side
|
||||
#define ILI9341_ORIENTATION_DOWN ILI9341_MADCTL_MX // 240x320 ; Cable on the upper side
|
||||
|
||||
#ifndef ILI9341_COLOR_RGB
|
||||
#define ILI9341_COLOR_BGR
|
||||
#define ILI9341_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9341_MADCTL_MV) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ILI9341_MADCTL_MX) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ILI9341_MADCTL_MY)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR
|
||||
#define ILI9341_COLOR ILI9341_MADCTL_BGR
|
||||
#elif TFT_COLOR == TFT_COLOR_RGB
|
||||
#define ILI9341_COLOR ILI9341_MADCTL_RGB
|
||||
#endif
|
||||
#ifndef ILI9341_ORIENTATION
|
||||
#define ILI9341_ORIENTATION ILI9341_ORIENTATION_LEFT
|
||||
#endif
|
||||
#define ILI9341_MADCTL_DATA (ILI9341_ORIENTATION | TERN(ILI9341_COLOR_BGR, ILI9341_MADCTL_BGR, ILI9341_MADCTL_RGB))
|
||||
|
||||
#define ILI9341_MADCTL_DATA (ILI9341_ORIENTATION) | (ILI9341_COLOR)
|
||||
|
||||
#define ILI9341_NOP 0x00 // No Operation
|
||||
#define ILI9341_SWRESET 0x01 // Software Reset
|
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft.h"
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -38,13 +38,17 @@
|
||||
#define ILI9488_ORIENTATION_LEFT ILI9488_MADCTL_MY | ILI9488_MADCTL_MX | ILI9488_MADCTL_MV // 480x320 ; Cable on the left side
|
||||
#define ILI9488_ORIENTATION_DOWN ILI9488_MADCTL_MX // 320x480 ; Cable on the upper side
|
||||
|
||||
#ifndef ILI9488_COLOR_RGB
|
||||
#define ILI9488_COLOR_BGR
|
||||
#define ILI9488_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9488_MADCTL_MV) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ILI9488_MADCTL_MX) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ILI9488_MADCTL_MY)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR
|
||||
#define ILI9488_COLOR ILI9488_MADCTL_BGR
|
||||
#elif TFT_COLOR == TFT_COLOR_RGB
|
||||
#define ILI9488_COLOR ILI9488_MADCTL_RGB
|
||||
#endif
|
||||
#ifndef ILI9488_ORIENTATION
|
||||
#define ILI9488_ORIENTATION ILI9488_ORIENTATION_LEFT
|
||||
#endif
|
||||
#define ILI9488_MADCTL_DATA (ILI9488_ORIENTATION | TERN(ILI9488_COLOR_BGR, ILI9488_MADCTL_BGR, ILI9488_MADCTL_RGB))
|
||||
|
||||
#define ILI9488_MADCTL_DATA (ILI9488_ORIENTATION) | (ILI9488_COLOR)
|
||||
|
||||
#define ILI9488_NOP 0x00 // No Operation
|
||||
#define ILI9488_SWRESET 0x01 // Software Reset
|
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft.h"
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -42,9 +42,30 @@
|
||||
#define R61505_DRVCTRL_GS 0x8000 // Gate Scan direction
|
||||
|
||||
// MKS Robin TFT v1.1 - 320x240 ; Cable on the left side
|
||||
#define R61505_DRVCTL_DATA R61505_DRVCTL_SS
|
||||
#define R61505_ETMOD_DATA R61505_ETMOD_BGR | R61505_ETMOD_ID1 | R61505_ETMOD_ID0 | R61505_ETMOD_AM
|
||||
#define R61505_DRVCTRL_GSDIR R61505_DRVCTRL_GS
|
||||
|
||||
#if TFT_ROTATION == TFT_ROTATE_180
|
||||
#define R61505_DRVCTL_DATA 0x0000
|
||||
#define R61505_DRVCTRL_DATA (0x2700 | R61505_DRVCTRL_GS)
|
||||
#else
|
||||
#define R61505_DRVCTL_DATA R61505_DRVCTL_SS
|
||||
#define R61505_DRVCTRL_DATA 0x2700
|
||||
#endif
|
||||
|
||||
/*
|
||||
#define R61505_ETMOD_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, R61505_ETMOD_AM) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, R61505_ETMOD_ID0) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, R61505_ETMOD_ID1)
|
||||
*/
|
||||
|
||||
#define R61505_ETMOD_ORIENTATION (R61505_ETMOD_AM | R61505_ETMOD_ID0 | R61505_ETMOD_ID1)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR
|
||||
#define R61505_ETMOD_COLOR R61505_ETMOD_BGR
|
||||
#elif TFT_COLOR == TFT_COLOR_RGB
|
||||
#define R61505_ETMOD_COLOR R61505_ETMOD_RGB
|
||||
#endif
|
||||
|
||||
#define R61505_ETMOD_DATA (R61505_ETMOD_ORIENTATION) | (R61505_ETMOD_COLOR)
|
||||
|
||||
|
||||
#define R61505_RDDID 0x00 // ID code - 0x1505
|
||||
@@ -141,7 +162,7 @@ static const uint16_t r61505_init[] = {
|
||||
ESC_REG(R61505_GAMCTRL9), 0x0700,
|
||||
ESC_REG(R61505_GAMCTRLA), 0x0A1F,
|
||||
|
||||
ESC_REG(R61505_DRVCTRL), R61505_DRVCTRL_GSDIR | 0x2700,
|
||||
ESC_REG(R61505_DRVCTRL), R61505_DRVCTRL_DATA,
|
||||
ESC_REG(R61505_BASE_IMAGE_CTRL), 0x0001,
|
||||
ESC_REG(R61505_VSCROLL_CTRL), 0x0000,
|
||||
|
131
Marlin/src/lcd/tft_io/ssd1963.h
Normal file
131
Marlin/src/lcd/tft_io/ssd1963.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#define SSD1963_MADCTL_MY 0x80 // Row Address Order
|
||||
#define SSD1963_MADCTL_MX 0x40 // Column Address Order
|
||||
#define SSD1963_MADCTL_MV 0x20 // Row/Column Exchange
|
||||
#define SSD1963_MADCTL_MH 0x10 // Horizontal Refresh Order
|
||||
#define SSD1963_MADCTL_BGR 0x08 // RGB-BGR ORDER
|
||||
#define SSD1963_MADCTL_RGB 0x00
|
||||
#define SSD1963_MADCTL_ML 0x04 // Vertical Refresh Order
|
||||
#define SSD1963_MADCTL_FH 0x02 // Flip Horizontal
|
||||
#define SSD1963_MADCTL_FV 0x01 // Flip Vertical
|
||||
|
||||
#define SSD1963_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, SSD1963_MADCTL_MV) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, SSD1963_MADCTL_FH) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, SSD1963_MADCTL_FV)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR
|
||||
#define SSD1963_COLOR SSD1963_MADCTL_BGR
|
||||
#elif TFT_COLOR == TFT_COLOR_RGB
|
||||
#define SSD1963_COLOR SSD1963_MADCTL_RGB
|
||||
#endif
|
||||
|
||||
#define SSD1963_MADCTL_DATA (SSD1963_ORIENTATION) | (SSD1963_COLOR)
|
||||
|
||||
#define SSD1963_NOP 0x00 // No Operation
|
||||
#define SSD1963_SWRESET 0x01 // Software reset
|
||||
#define SSD1963_RDDPM 0x0A // Read Display Power Mode
|
||||
#define SSD1963_RDDMADCTL 0x0B // Read Display MADCTL
|
||||
#define SSD1963_RDDCOLMOD 0x0C // Read Display Pixel Format
|
||||
#define SSD1963_RDDIM 0x0D // Read Display Image Mode
|
||||
#define SSD1963_RDDSM 0x0E // Read Display Signal Mode
|
||||
#define SSD1963_SLPIN 0x10 // Sleep In
|
||||
#define SSD1963_SLPOUT 0x11 // Sleep Out
|
||||
#define SSD1963_PTLON 0x12 // Partial Display Mode On
|
||||
#define SSD1963_NORON 0x13 // Normal Display Mode On
|
||||
#define SSD1963_INVOFF 0x20 // Display Inversion Off
|
||||
#define SSD1963_INVON 0x21 // Display Inversion On
|
||||
#define SSD1963_GAMSET 0x26 // Gamma Set
|
||||
#define SSD1963_DISPOFF 0x28 // Display Off
|
||||
#define SSD1963_DISPON 0x29 // Display On
|
||||
#define SSD1963_CASET 0x2A // Column Address Set
|
||||
#define SSD1963_RASET 0x2B // Row Address Set
|
||||
#define SSD1963_RAMWR 0x2C // Memory Write
|
||||
#define SSD1963_RAMRD 0x2E // Memory Read
|
||||
#define SSD1963_PTLAR 0x30 // Partial Area
|
||||
#define SSD1963_VSCRDEF 0x33 // Vertical Scrolling Definition
|
||||
#define SSD1963_TEOFF 0x34 // Tearing Effect Line OFF
|
||||
#define SSD1963_TEON 0x35 // Tearing Effect Line ON
|
||||
#define SSD1963_MADCTL 0x36 // Memory Data Access Control
|
||||
#define SSD1963_VSCSAD 0x37 // Vertical Scroll Start Address of RAM
|
||||
#define SSD1963_IDMOFF 0x38 // Idle Mode Off
|
||||
#define SSD1963_IDMON 0x39 // Idle Mode On
|
||||
#define SSD1963_WRMEMC 0x3C // Write Memory Continue
|
||||
#define SSD1963_RDMEMC 0x3E // Read Memory Continue
|
||||
#define SSD1963_STE 0x44 // Set Tear Scanline
|
||||
#define SSD1963_GSCAN 0x45 // Get Scanline
|
||||
#define SSD1963_WRDISBV 0x51 // Write Display Brightness
|
||||
#define SSD1963_RDDISBV 0x52 // Read Display Brightness
|
||||
#define SSD1963_WRCTRLD 0x53 // Write CTRL Display
|
||||
#define SSD1963_RDCTRLD 0x54 // Read CTRL Value Display
|
||||
#define SSD1963_WRCACE 0x55 // Write Content Adaptive Brightness Control and Color Enhancement
|
||||
#define SSD1963_RDCABC 0x56 // Read Content Adaptive Brightness Control
|
||||
#define SSD1963_WRCABCMB 0x5E // Write CABC Minimum Brightness
|
||||
#define SSD1963_RDCABCMB 0x5F // Read CABC Minimum Brightness
|
||||
#define SSD1963_RDABCSDR 0x68 // Read Automatic Brightness Control Self-Diagnostic Result
|
||||
#define SSD1963_RDDDB 0xA1 // Read Device Descriptor Block
|
||||
#define SSD1963_SLCDMODE 0xB0 // Set the LCD panel mode and resolution
|
||||
#define SSD1963_SHSYNC 0xB4 // Set HSYNC
|
||||
#define SSD1963_GHSYNC 0xB5 // Get HSYNC
|
||||
#define SSD1963_SVSYNC 0xB6 // Set VSYNC
|
||||
#define SSD1963_GVSYNC 0xB7 // Get VSYNC
|
||||
#define SSD1963_SGPIOCFG 0xB8 // Set GPIO Conf
|
||||
#define SSD1963_SGPIOV 0xBA // Set GPIO Value
|
||||
#define SSD1963_SPWMCFG 0xBE // Set PWM Conf
|
||||
#define SSD1963_GPWMCFG 0xBF // Get PWM Conf
|
||||
#define SSD1963_SDBCCFG 0xD0 // Set Dynamic Back Light Config
|
||||
#define SSD1963_GDBCCFG 0xD1 // Get Dynamic Back Light Config
|
||||
#define SSD1963_PLLON 0xE0 // PLL Enable
|
||||
#define SSD1963_PLLMN 0xE2 // Set PLL Multiplier
|
||||
#define SSD1963_SLSHIFT 0xE6 // Set the LSHIFT (pixel clock) frequency
|
||||
#define SSD1963_COLMOD 0xF0 // Interface Pixel Format
|
||||
|
||||
static const uint16_t ssd1963_init[] = {
|
||||
DATASIZE_8BIT,
|
||||
ESC_REG(SSD1963_PLLMN), 0x0023, 0x0002, 0x0054,
|
||||
ESC_REG(SSD1963_PLLON), 0x0001, ESC_DELAY(10),
|
||||
ESC_REG(SSD1963_PLLON), 0x0003, ESC_DELAY(10),
|
||||
ESC_REG(SSD1963_SWRESET), ESC_DELAY(100),
|
||||
|
||||
ESC_REG(SSD1963_SLSHIFT), 0x0001, 0x001F, 0x00FF,
|
||||
ESC_REG(SSD1963_SLCDMODE), 0x0020, 0x0000, 0x0001, 0x00DF, 0x0001, 0x000F, 0x0000,
|
||||
ESC_REG(SSD1963_SHSYNC), 0x0002, 0x0013, 0x0000, 0x0008, 0x002B, 0x0000, 0x0002, 0x0000,
|
||||
ESC_REG(SSD1963_SVSYNC), 0x0001, 0x0020, 0x0000, 0x0004, 0x000C, 0x0000, 0x0002,
|
||||
ESC_REG(SSD1963_SGPIOV), 0x000F,
|
||||
ESC_REG(SSD1963_SGPIOCFG), 0x0007, 0x0001,
|
||||
|
||||
ESC_REG(SSD1963_MADCTL), SSD1963_MADCTL_DATA,
|
||||
ESC_REG(SSD1963_COLMOD), 0x0003, ESC_DELAY(1),//RBG 565
|
||||
|
||||
ESC_REG(SSD1963_NORON),
|
||||
ESC_REG(SSD1963_DISPON),
|
||||
|
||||
ESC_REG(SSD1963_SPWMCFG), 0x0006, 0x00f0, 0x0001, 0x00f0, 0x0000, 0x0000,
|
||||
ESC_REG(SSD1963_SDBCCFG), 0x000D,
|
||||
ESC_END
|
||||
};
|
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft.h"
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -38,9 +38,17 @@
|
||||
#define ST7735_ORIENTATION_LEFT ST7735_MADCTL_MV | ST7735_MADCTL_MX // 160x128 ; Cable on the left side
|
||||
#define ST7735_ORIENTATION_DOWN ST7735_MADCTL_MX | ST7735_MADCTL_MY // 128x160 ; Cable on the lower side
|
||||
|
||||
//#define ST7735_COLOR_BGR
|
||||
#define ST7735_ORIENTATION ST7735_ORIENTATION_DOWN
|
||||
#define ST7735_MADCTL_DATA (ST7735_ORIENTATION | TERN(ST7735_COLOR_BGR, ST7735_MADCTL_BGR, ST7735_MADCTL_RGB))
|
||||
#define ST7735_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7735_MADCTL_MV) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7735_MADCTL_MX) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ST7735_MADCTL_MY)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_RGB
|
||||
#define ST7735_COLOR ST7735_MADCTL_RGB
|
||||
#elif TFT_COLOR == TFT_COLOR_BGR
|
||||
#define ST7735_COLOR ST7735_MADCTL_BGR
|
||||
#endif
|
||||
|
||||
#define ST7735_MADCTL_DATA (ST7735_ORIENTATION) | (ST7735_COLOR)
|
||||
|
||||
#define ST7735_NOP 0x00 // No Operation
|
||||
#define ST7735_SWRESET 0x01 // Software reset
|
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft.h"
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -38,11 +38,17 @@
|
||||
#define ST7789V_ORIENTATION_LEFT ST7789V_MADCTL_MY | ST7789V_MADCTL_MV // 320x240 ; Cable on the left side
|
||||
#define ST7789V_ORIENTATION_DOWN 0 // 240x320 ; Cable on the lower side
|
||||
|
||||
//#define ST7789V_COLOR_BGR
|
||||
#ifndef ST7789V_ORIENTATION
|
||||
#define ST7789V_ORIENTATION ST7789V_ORIENTATION_LEFT
|
||||
#define ST7789V_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7789V_MADCTL_MV) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7789V_MADCTL_MX) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ST7789V_MADCTL_MY)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_RGB
|
||||
#define ST7789V_COLOR ST7789V_MADCTL_RGB
|
||||
#elif TFT_COLOR == TFT_COLOR_BGR
|
||||
#define ST7789V_COLOR ST7789V_MADCTL_BGR
|
||||
#endif
|
||||
#define ST7789V_MADCTL_DATA (ST7789V_ORIENTATION | TERN(ST7789V_COLOR_BGR, ST7789V_MADCTL_BGR, ST7789V_MADCTL_RGB))
|
||||
|
||||
#define ST7789V_MADCTL_DATA (ST7789V_ORIENTATION) | (ST7789V_COLOR)
|
||||
|
||||
#define ST7789V_NOP 0x00 // No Operation
|
||||
#define ST7789V_SWRESET 0x01 // Software reset
|
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "tft.h"
|
||||
#include "tft_io.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -33,9 +33,17 @@
|
||||
#define ST7796S_MADCTL_RGB 0x00
|
||||
#define ST7796S_MADCTL_MH 0x04 // Horizontal Refresh Order
|
||||
|
||||
#define ST7796S_COLOR_BGR
|
||||
#define ST7796S_ORIENTATION ST7796S_MADCTL_MV
|
||||
#define ST7796S_MADCTL_DATA (ST7796S_ORIENTATION | TERN(ST7796S_COLOR_BGR, ST7796S_MADCTL_BGR, ST7796S_MADCTL_RGB))
|
||||
#define ST7796S_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7796S_MADCTL_MV) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7796S_MADCTL_MX) | \
|
||||
IF_0((TFT_ORIENTATION) & TFT_INVERT_Y, ST7796S_MADCTL_MY)
|
||||
|
||||
#if !defined(TFT_COLOR) || TFT_COLOR == TFT_COLOR_BGR
|
||||
#define ST7796S_COLOR ST7796S_MADCTL_BGR
|
||||
#elif TFT_COLOR == TFT_COLOR_RGB
|
||||
#define ST7796S_COLOR ST7796S_MADCTL_RGB
|
||||
#endif
|
||||
|
||||
#define ST7796S_MADCTL_DATA (ST7796S_ORIENTATION) | (ST7796S_COLOR)
|
||||
|
||||
#define ST7796S_NOP 0x00 // No Operation
|
||||
#define ST7796S_SWRESET 0x01 // Software reset
|
226
Marlin/src/lcd/tft_io/tft_io.cpp
Normal file
226
Marlin/src/lcd/tft_io/tft_io.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tft_io.h"
|
||||
|
||||
#if HAS_SPI_TFT || HAS_FSMC_TFT
|
||||
|
||||
#include "st7735.h"
|
||||
#include "st7789v.h"
|
||||
#include "st7796s.h"
|
||||
#include "r65105.h"
|
||||
#include "ili9328.h"
|
||||
#include "ili9341.h"
|
||||
#include "ili9488.h"
|
||||
#include "ssd1963.h"
|
||||
|
||||
#define DEBUG_OUT ENABLED(DEBUG_GRAPHICAL_TFT)
|
||||
#include "../../core/debug_out.h"
|
||||
|
||||
TFT_IO_DRIVER TFT_IO::io;
|
||||
uint32_t TFT_IO::lcd_id = 0xFFFFFFFF;
|
||||
|
||||
void TFT_IO::InitTFT() {
|
||||
if (lcd_id != 0xFFFFFFFF) return;
|
||||
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, LOW);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(TFT_RESET)
|
||||
OUT_WRITE(TFT_RESET_PIN, HIGH);
|
||||
delay(10);
|
||||
OUT_WRITE(TFT_RESET_PIN, LOW);
|
||||
delay(10);
|
||||
OUT_WRITE(TFT_RESET_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT));
|
||||
#endif
|
||||
|
||||
// io.Init();
|
||||
delay(100);
|
||||
|
||||
#if TFT_DRIVER != AUTO
|
||||
lcd_id = TFT_DRIVER;
|
||||
#endif
|
||||
|
||||
#if TFT_DRIVER == ST7735
|
||||
write_esc_sequence(st7735_init);
|
||||
#elif TFT_DRIVER == SSD1963
|
||||
write_esc_sequence(ssd1963_init);
|
||||
#elif TFT_DRIVER == ST7789
|
||||
write_esc_sequence(st7789v_init);
|
||||
#elif TFT_DRIVER == ST7796
|
||||
write_esc_sequence(st7796s_init);
|
||||
#elif TFT_DRIVER == R61505
|
||||
write_esc_sequence(r61505_init);
|
||||
#elif TFT_DRIVER == ILI9328
|
||||
write_esc_sequence(ili9328_init);
|
||||
#elif TFT_DRIVER == ILI9341
|
||||
write_esc_sequence(ili9341_init);
|
||||
#elif TFT_DRIVER == ILI9488
|
||||
write_esc_sequence(ili9488_init);
|
||||
#elif TFT_DRIVER == LERDGE_ST7796
|
||||
lcd_id = ST7796;
|
||||
write_esc_sequence(lerdge_st7796s_init);
|
||||
|
||||
#elif TFT_DRIVER == AUTO // autodetect
|
||||
|
||||
lcd_id = io.GetID() & 0xFFFF;
|
||||
|
||||
switch (lcd_id) {
|
||||
case ST7796: // ST7796S 480x320
|
||||
DEBUG_ECHO_MSG(" ST7796S");
|
||||
write_esc_sequence(st7796s_init);
|
||||
break;
|
||||
case ST7789: // ST7789V 320x240
|
||||
DEBUG_ECHO_MSG(" ST7789V");
|
||||
write_esc_sequence(st7789v_init);
|
||||
break;
|
||||
case SSD1963: // SSD1963
|
||||
DEBUG_ECHO_MSG(" SSD1963");
|
||||
write_esc_sequence(ssd1963_init);
|
||||
break;
|
||||
case ST7735: // ST7735 160x128
|
||||
DEBUG_ECHO_MSG(" ST7735");
|
||||
write_esc_sequence(st7735_init);
|
||||
break;
|
||||
case R61505: // R61505U 320x240
|
||||
DEBUG_ECHO_MSG(" R61505U");
|
||||
write_esc_sequence(r61505_init);
|
||||
break;
|
||||
case ILI9328: // ILI9328 320x240
|
||||
DEBUG_ECHO_MSG(" ILI9328");
|
||||
write_esc_sequence(ili9328_init);
|
||||
break;
|
||||
case ILI9341: // ILI9341 320x240
|
||||
DEBUG_ECHO_MSG(" ILI9341");
|
||||
write_esc_sequence(ili9341_init);
|
||||
break;
|
||||
case ILI9488: // ILI9488 480x320
|
||||
case ILI9488_ID1: // 0x8066 ILI9488 480x320
|
||||
DEBUG_ECHO_MSG(" ILI9488");
|
||||
write_esc_sequence(ili9488_init);
|
||||
break;
|
||||
default:
|
||||
lcd_id = 0;
|
||||
}
|
||||
#else
|
||||
#error Unsupported TFT driver
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(TFT_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT)
|
||||
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TFT_IO::set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
|
||||
#ifdef OFFSET_X
|
||||
Xmin += OFFSET_X; Xmax += OFFSET_X;
|
||||
#endif
|
||||
#ifdef OFFSET_Y
|
||||
Ymin += OFFSET_Y; Ymax += OFFSET_Y;
|
||||
#endif
|
||||
|
||||
switch (lcd_id) {
|
||||
case ST7735: // ST7735 160x128
|
||||
case ST7789: // ST7789V 320x240
|
||||
case ST7796: // ST7796 480x320
|
||||
case ILI9341: // ILI9341 320x240
|
||||
case ILI9488: // ILI9488 480x320
|
||||
case SSD1963: // SSD1963
|
||||
case ILI9488_ID1: // 0x8066 ILI9488 480x320
|
||||
io.DataTransferBegin(DATASIZE_8BIT);
|
||||
|
||||
// CASET: Column Address Set
|
||||
io.WriteReg(ILI9341_CASET);
|
||||
io.WriteData((Xmin >> 8) & 0xFF);
|
||||
io.WriteData(Xmin & 0xFF);
|
||||
io.WriteData((Xmax >> 8) & 0xFF);
|
||||
io.WriteData(Xmax & 0xFF);
|
||||
|
||||
// RASET: Row Address Set
|
||||
io.WriteReg(ILI9341_PASET);
|
||||
io.WriteData((Ymin >> 8) & 0xFF);
|
||||
io.WriteData(Ymin & 0xFF);
|
||||
io.WriteData((Ymax >> 8) & 0xFF);
|
||||
io.WriteData(Ymax & 0xFF);
|
||||
|
||||
// RAMWR: Memory Write
|
||||
io.WriteReg(ILI9341_RAMWR);
|
||||
break;
|
||||
case R61505: // R61505U 320x240
|
||||
case ILI9328: // ILI9328 320x240
|
||||
io.DataTransferBegin(DATASIZE_16BIT);
|
||||
|
||||
// Mind the mess: with landscape screen orientation 'Horizontal' is Y and 'Vertical' is X
|
||||
io.WriteReg(ILI9328_HASTART);
|
||||
io.WriteData(Ymin);
|
||||
io.WriteReg(ILI9328_HAEND);
|
||||
io.WriteData(Ymax);
|
||||
io.WriteReg(ILI9328_VASTART);
|
||||
io.WriteData(Xmin);
|
||||
io.WriteReg(ILI9328_VAEND);
|
||||
io.WriteData(Xmax);
|
||||
|
||||
io.WriteReg(ILI9328_HASET);
|
||||
io.WriteData(Ymin);
|
||||
io.WriteReg(ILI9328_VASET);
|
||||
io.WriteData(Xmin);
|
||||
|
||||
io.WriteReg(ILI9328_RAMWR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
io.DataTransferEnd();
|
||||
}
|
||||
|
||||
void TFT_IO::write_esc_sequence(const uint16_t *Sequence) {
|
||||
uint16_t dataWidth, data;
|
||||
|
||||
dataWidth = *Sequence++;
|
||||
io.DataTransferBegin(dataWidth);
|
||||
|
||||
for (;;) {
|
||||
data = *Sequence++;
|
||||
if (data != 0xFFFF) {
|
||||
io.WriteData(data);
|
||||
continue;
|
||||
}
|
||||
data = *Sequence++;
|
||||
if (data == 0x7FFF) return;
|
||||
if (data == 0xFFFF)
|
||||
io.WriteData(0xFFFF);
|
||||
else if (data & 0x8000)
|
||||
delay(data & 0x7FFF);
|
||||
else if ((data & 0xFF00) == 0)
|
||||
io.WriteReg(data);
|
||||
}
|
||||
|
||||
io.DataTransferEnd();
|
||||
}
|
||||
|
||||
#endif // HAS_SPI_TFT || HAS_FSMC_TFT
|
124
Marlin/src/lcd/tft_io/tft_io.h
Normal file
124
Marlin/src/lcd/tft_io/tft_io.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_SPI_TFT || HAS_FSMC_TFT
|
||||
|
||||
#if HAS_SPI_TFT
|
||||
#include HAL_PATH(../../HAL, tft/tft_spi.h)
|
||||
#elif HAS_FSMC_TFT
|
||||
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
|
||||
#else
|
||||
#error "TFT IO only supports SPI or FSMC interface"
|
||||
#endif
|
||||
|
||||
#define TFT_EXCHANGE_XY (1UL << 1)
|
||||
#define TFT_INVERT_X (1UL << 2)
|
||||
#define TFT_INVERT_Y (1UL << 3)
|
||||
|
||||
#define TFT_NO_ROTATION (0x00)
|
||||
#define TFT_ROTATE_90 (TFT_EXCHANGE_XY | TFT_INVERT_X)
|
||||
#define TFT_ROTATE_180 (TFT_INVERT_X | TFT_INVERT_Y)
|
||||
#define TFT_ROTATE_270 (TFT_EXCHANGE_XY | TFT_INVERT_Y)
|
||||
|
||||
#define TFT_MIRROR_X (TFT_INVERT_Y)
|
||||
#define TFT_MIRROR_Y (TFT_INVERT_X)
|
||||
|
||||
#define TFT_ROTATE_90_MIRROR_X (TFT_ROTATE_90 ^ TFT_INVERT_Y)
|
||||
#define TFT_ROTATE_90_MIRROR_Y (TFT_ROTATE_90 ^ TFT_INVERT_X)
|
||||
|
||||
#define TFT_ROTATE_180_MIRROR_X (TFT_ROTATE_180 ^ TFT_INVERT_Y)
|
||||
#define TFT_ROTATE_180_MIRROR_Y (TFT_ROTATE_180 ^ TFT_INVERT_X)
|
||||
|
||||
#define TFT_ROTATE_270_MIRROR_X (TFT_ROTATE_270 ^ TFT_INVERT_Y)
|
||||
#define TFT_ROTATE_270_MIRROR_Y (TFT_ROTATE_270 ^ TFT_INVERT_X)
|
||||
|
||||
// TFT_ROTATION is user configurable
|
||||
#ifndef TFT_ROTATION
|
||||
#define TFT_ROTATION TFT_NO_ROTATION
|
||||
#endif
|
||||
|
||||
|
||||
// TFT_ORIENTATION is the "sum" of TFT_DEFAULT_ORIENTATION plus user TFT_ROTATION
|
||||
#define TFT_ORIENTATION ((TFT_DEFAULT_ORIENTATION) ^ (TFT_ROTATION))
|
||||
|
||||
#define TFT_COLOR_RGB (1UL << 3)
|
||||
#define TFT_COLOR_BGR (1UL << 4)
|
||||
|
||||
// Each TFT Driver is responsible for its default color mode.
|
||||
// #ifndef TFT_COLOR
|
||||
// #define TFT_COLOR TFT_COLOR_RGB
|
||||
// #endif
|
||||
|
||||
#define SSD1963 0x5761
|
||||
#define ST7735 0x89F0
|
||||
#define ST7789 0x8552
|
||||
#define ST7796 0x7796
|
||||
#define R61505 0x1505
|
||||
#define ILI9328 0x9328
|
||||
#define ILI9341 0x9341
|
||||
#define ILI9488 0x9488
|
||||
#define ILI9488_ID1 0x8066 //Some ILI9488 have 0x8066 in the 0x04
|
||||
#define LERDGE_ST7796 0xFFFE
|
||||
#define AUTO 0xFFFF
|
||||
|
||||
#ifndef TFT_DRIVER
|
||||
#define TFT_DRIVER AUTO
|
||||
#endif
|
||||
|
||||
#define ESC_REG(x) 0xFFFF, 0x00FF & (uint16_t)x
|
||||
#define ESC_DELAY(x) 0xFFFF, 0x8000 | (x & 0x7FFF)
|
||||
#define ESC_END 0xFFFF, 0x7FFF
|
||||
#define ESC_FFFF 0xFFFF, 0xFFFF
|
||||
|
||||
class TFT_IO {
|
||||
public:
|
||||
static TFT_IO_DRIVER io;
|
||||
|
||||
static void InitTFT();
|
||||
static void set_window(uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax);
|
||||
static void write_esc_sequence(const uint16_t *Sequence);
|
||||
|
||||
// Deletaged methods
|
||||
inline static void Init() { io.Init(); };
|
||||
inline static bool isBusy() { return io.isBusy(); };
|
||||
inline static void Abort() { io.Abort(); };
|
||||
inline static uint32_t GetID() { return io.GetID(); };
|
||||
|
||||
inline static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) { io.DataTransferBegin(DataWidth); }
|
||||
inline static void DataTransferEnd() { io.DataTransferEnd(); };
|
||||
// inline static void DataTransferAbort() { io.DataTransferAbort(); };
|
||||
|
||||
inline static void WriteData(uint16_t Data) { io.WriteData(Data); };
|
||||
inline static void WriteReg(uint16_t Reg) { io.WriteReg(Reg); };
|
||||
|
||||
inline static void WriteSequence(uint16_t *Data, uint16_t Count) { io.WriteSequence(Data, Count); };
|
||||
// static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
|
||||
inline static void WriteMultiple(uint16_t Color, uint32_t Count) { io.WriteMultiple(Color, Count); };
|
||||
|
||||
protected:
|
||||
static uint32_t lcd_id;
|
||||
};
|
||||
|
||||
#endif // HAS_SPI_TFT || HAS_FSMC_TFT
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user