Compare commits

...

40 commits

Author SHA1 Message Date
thinkyhead
ba2939b1dc Fix bilinear_line_to_destination definition
See #19431
2020-10-30 00:24:29 -05:00
Jason Smith
ee7476a0bf
Update "Bug Report" template (#19906) 2020-10-27 17:48:06 -05:00
Scott Lahteine
88a2ac92d5 Marlin 2.0.7.2 2020-10-21 18:16:38 -05:00
Jason Smith
3ccb3801f2 Fix SAMD Serial name macro (#19765) 2020-10-21 18:16:38 -05:00
Serhiy-K
cc7fbabc96 Fix HAL/STM32 FastIO for analog pins (#19735) 2020-10-21 18:16:38 -05:00
Scott Lahteine
28a9708ddb Don't define IS_ULTIPANEL empty 2020-10-21 18:16:00 -05:00
Jason Smith
d896dedf9b Add NUCLEO-F767ZI dev board (#19373)
Co-authored-by: Lorenzo Delana <lorenzo.delana@gmail.com>
2020-10-16 16:42:39 -05:00
Keith Bennett
00709017e2 If needed, home before G34 (#19713) 2020-10-16 16:42:39 -05:00
Victor Oliveira
b7d9b05952 TFT followup fixes (#19710) 2020-10-16 16:42:37 -05:00
Victor Oliveira
f7f1224941 Watchdog Refresh for LVGL Asset Load (#19724) 2020-10-16 16:42:15 -05:00
Jason Smith
fd8d83b7c8 Fix mega2560ext environment (#19730) 2020-10-16 16:42:15 -05:00
thinkyhead
52fc0b896d [cron] Bump distribution date (2020-10-15) 2020-10-16 16:42:15 -05:00
thinkyhead
ba045d6852 [cron] Bump distribution date (2020-10-14) 2020-10-16 16:42:15 -05:00
Jason Smith
54bdcb4691 Fix SET_SOFT_ENDSTOP_LOOSE w/out soft endstops (#19734) 2020-10-16 16:42:15 -05:00
Scott Lahteine
2a2666326b Simple bool in soft_endstops_t 2020-10-16 16:42:15 -05:00
thinkyhead
3bba5d55bf [cron] Bump distribution date (2020-10-13) 2020-10-16 16:42:15 -05:00
thinkyhead
5d07d83e78 [cron] Bump distribution date (2020-10-12) 2020-10-16 16:40:25 -05:00
Jason Smith
37f97bc013 Fix various errors, warnings in example config builds (#19686)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2020-10-16 16:40:14 -05:00
thinkyhead
6d31bbe2bf [cron] Bump distribution date (2020-10-11) 2020-10-16 16:39:55 -05:00
Victor Oliveira
e2e1776a14 Restore correct STM32 port-bits code (#19678) 2020-10-16 16:39:55 -05:00
Serhiy-K
bd196e7efc Fixes for TFTGLCD Panel, FastIO (#19614) 2020-10-16 16:39:55 -05:00
Earle F. Philhower, III
dffe7b9072 Add loose soft endstop state, apply to UBL fine-tune (#19681)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2020-10-16 16:39:55 -05:00
Jason Smith
2b326ebc84 Add D100 Watchdog Test (#19697) 2020-10-16 16:39:55 -05:00
Jason Smith
f4ff6a673f Allow MAX31865 resistance values configuration (#19695) 2020-10-16 16:39:55 -05:00
qwewer0
cc915a25ed Add REPORT_TRAMMING_MM option (#19682)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2020-10-16 16:39:55 -05:00
Jason Smith
600870f22b Fix motion compile w/out probe-oriented settings (#19684) 2020-10-16 16:39:55 -05:00
Jason Smith
04882e2f34 Fix I2C_ADDRESS sign warning (#19685) 2020-10-16 16:39:55 -05:00
Jason Smith
c6cf3da276 Fix various errors, warnings in example config builds (#19686)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2020-10-16 16:39:55 -05:00
Jason Smith
8a5c3782b8 Fix at90usb1286 build (#19687)
* Skip check for USBCON during dependency detection
* Ignore incompatible Teensy_ADC library, which requires Teensy >= 3
* Add IS_AT90USB

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2020-10-16 16:39:55 -05:00
Scott Lahteine
beb17d8855 Digipots refactor / cleanup (#19690) 2020-10-16 16:39:55 -05:00
Scott Lahteine
4ee717f7c4 Save PLR on resume from pause (#19676)
Co-Authored-By: shahab <32130261+SHBnik@users.noreply.github.com>
2020-10-16 16:39:55 -05:00
Victor Oliveira
e680196c59 Restore correct STM32 port-bits code (#19678) 2020-10-16 16:39:55 -05:00
Serhiy-K
ce92abfe47 Fixes for TFTGLCD Panel, FastIO (#19614) 2020-10-16 16:39:55 -05:00
Victor Oliveira
50410aaeaa Fix UTF8 handling for Color UI (#19708) 2020-10-16 16:39:55 -05:00
Victor Oliveira
35c40bc376 Implement wait_for_user for Color UI (#19694) 2020-10-16 16:39:55 -05:00
Victor Oliveira
aae644c507 Option to prevent (extra) Watchdog init on STM32 (#19693) 2020-10-16 16:39:55 -05:00
Scott Lahteine
ce830f8a71 Fix screen click reading too often (#19696)
Co-authored-by: andreibobirica <39415547+andreibobirica@users.noreply.github.com>
2020-10-16 16:39:55 -05:00
Keith Bennett
d3d423a322 Sanity-check mutually-exclusive G34 features (#19706) 2020-10-16 16:39:55 -05:00
InsanityAutomation
8b060a3902 G34 Mechanical Gantry Calibration (like Prusa M915) (#18972)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2020-10-16 16:39:55 -05:00
Victor Oliveira
faae900747 TFT Refactoring (#19192)
* split tft folder in two: tft for color ui; tft_io for shared tft code

* after the files got moved, now the code was moved to the right place

* classic ui using TFT IO init lcd codes

* feature to compile tft_io when enabled

* compiling fix

* lvgl spi tft working with tft io init codes

* there is no need for separeted fsmc and spi class in lvgl anymore, as tft io handle everything

* remove debug

* base for TFT rotation and mirroring API, and ILI9488 support

* ST7796S rotate and mirror support

* ST7789V rotate and mirror support

* ST7735 rotate and mirror support

* ILI9341 rotate and mirror support

* ILI9328 rotate and mirror support

* R61505 rotate and mirror support

* MKS TFT definitions

* more configs for mks tfts

* update config

* naming typo

* to configure the user interface

* ANYCUBIC_TFT35

* tft configs

* support for SSD1963

* tft display types

* updated conditionals lcd; first board fully working with the new code - all 3 ui!

* compatiblity

* changed name

* move classic ui file name

* rename TURN -> ROTATE

* GRAPHICAL_TFT_ROTATE_180 deprecated

* first fsmc board fully working - chitu v5

* mks robin nano v1.2 + tft 35 ok!

* right pin name

* anycubic tft tested in a TRIGORILLA_PRO

* chitu v6

* nano 32 tft orientation

* mks tft43

* mks tft43 rotation

* fixed LONGER LK tft setup

* GRAPHICAL_TFT_UPSCALE defined by the display type

* better offsets defaults

* Update Configuration.h

* Update tft_fsmc.cpp

* Update Conditionals_LCD.h

* Tweak comments

* update nano tests

* Revert "update nano tests"

This reverts commit a071ebbfad30e28855a4a5695ec8a726542a1a65.

* default tft

* outdated comments

* to not break non-vscode builds

* upscale tft 35

* support tft 180 rotation for color ui

* Each TFT Driver is responsible for its default color mode.

* use auto detect in mks displays, because some of them could be shipped with diferent drivers

* extra s

* unused code

* wrong -1

* missing mirror options

* Smaller regex pattern

* Comment updates

* Clean up old defines

* Apply pins formatting

* GRAPHICAL_TFT_ROTATE_180 => TFT_ROTATE_180

* MKS_ROBIN_TFT_V1_1R

* merge fix

* correct resolution

* auto is default, dont need be there, and it will allow the user to configure it even for named displays

* to not use rotation with MKS_ROBIN_TFT_V1_1R

* i like () in macros

* avoid sleepy commits

* default for st7789 is rgb

* nano follow up

* to allow ili9328 rotation

* default is rgb

* boards merge follow up

* to match bootloader orientation

* HAS_TOUCH_XPT2046 is not hal specific anymore

* lets not forget LPC

* 180 rotation for ili9328 and R61505

* Clean up whitespace

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2020-10-16 16:39:55 -05:00
137 changed files with 2200 additions and 2113 deletions

View file

@ -9,35 +9,51 @@ assignees: ''
<!-- <!--
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md Please follow the instructions below. Failure to do so may result in your issue being closed.
Do you want to ask a question? Are you looking for support? Please don't post here. Instead please use one of the support links at https://github.com/MarlinFirmware/Marlin/issues/new/choose ### Before Reporting a Bug
Before filing an issue be sure to test the "bugfix" branches to see whether the issue has been resolved. 1. Test with the `bugfix-2.0.x` branch to see whether the issue still exists.
2. Get troubleshooting help from the Marlin community to confirm it's a bug and not just a configuration error. Links at https://github.com/MarlinFirmware/Marlin/issues/new/choose
### Instructions
1. Fill out every section of the template below.
2. Always attach configuration files, regardless of whether you think they are involved.
3. Read and understand Marlin's Code of Conduct. By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md
--> -->
### Bug Description ### Bug Description
<!-- Description of the bug --> <!-- Describe the bug in this section. (You can remove this invisible comment.) -->
### My Configurations ### Configuration Files
**Required:** Please include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files. **Required:** Include a ZIP file containing `Configuration.h` and `Configuration_adv.h`.
If you've made any other modifications describe them in detail here.
### Steps to Reproduce ### Steps to Reproduce
<!-- Please describe the steps needed to reproduce the issue --> <!-- Describe the steps needed to reproduce the issue. (You can remove this invisible comment.) -->
1. [First Step] 1. [First Step]
2. [Second Step] 2. [Second Step]
3. [and so on...] 3. [and so on...]
**Expected behavior:** [What you expect to happen] **Expected behavior:**
**Actual behavior:** [What actually happens] <!-- Describe what you expected to happen here. (You can remove this invisible comment.) -->
**Actual behavior:**
<!-- Describe what actually happens here. (You can remove this invisible comment.) -->
#### Additional Information #### Additional Information
* Provide pictures or links to videos that clearly demonstrate the issue. * Provide pictures or links to videos that clearly demonstrate the issue.
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines. * See [Contributing to Marlin](https://github.com/MarlinFirmware/Marlin/blob/2.0.x/.github/contributing.md) for additional guidelines.

View file

@ -431,6 +431,12 @@
#define DUMMY_THERMISTOR_998_VALUE 25 #define DUMMY_THERMISTOR_998_VALUE 25
#define DUMMY_THERMISTOR_999_VALUE 100 #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 // 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. // from the two sensors differ too much the print will be aborted.
//#define TEMP_SENSOR_1_AS_REDUNDANT //#define TEMP_SENSOR_1_AS_REDUNDANT
@ -2198,43 +2204,47 @@
//=============================== Graphical TFTs ============================== //=============================== Graphical TFTs ==============================
//============================================================================= //=============================================================================
// /**
// TFT display with optional touch screen * TFT Type - Select your Display type
// Color Marlin UI with standard menu system *
// * Available options are:
//#define TFT_320x240 * MKS_TS35_V2_0,
//#define TFT_320x240_SPI * MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35,
//#define TFT_480x320 * MKS_ROBIN_TFT43, MKS_ROBIN_TFT_V1_1R
//#define TFT_480x320_SPI * 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 * TFT UI - User Interface Selection. Enable one of the following options:
// Mandatory for SPI screens with no MISO line *
// Available drivers are: ST7735, ST7789, ST7796, R61505, ILI9328, ILI9341, ILI9488 * TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled
// * TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities
//#define TFT_DRIVER AUTO * 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) * TFT Rotation. Set to one of the following values:
// Upscaled 128x64 Marlin UI *
// * TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y,
//#define SPI_GRAPHICAL_TFT * 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
// FSMC display (MKS Robin, Alfawise U20, JGAurora A5S, REXYZ A1, etc.) */
// Upscaled 128x64 Marlin UI //#define TFT_ROTATION TFT_NO_ROTATION
//
//#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
//============================================================================= //=============================================================================
//============================ Other Controllers ============================ //============================ Other Controllers ============================

View file

@ -806,11 +806,9 @@
#define TRAMMING_POINT_NAME_3 "Back-Right" #define TRAMMING_POINT_NAME_3 "Back-Right"
#define TRAMMING_POINT_NAME_4 "Back-Left" #define TRAMMING_POINT_NAME_4 "Back-Left"
// Enable to restore leveling setup after operation #define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation
#define RESTORE_LEVELING_AFTER_G35 //#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
// Add a menu item for Assisted Tramming
//#define ASSISTED_TRAMMING_MENU_ITEM
/** /**
* Screw thread: * Screw thread:
@ -1562,10 +1560,9 @@
#endif #endif
// //
// FSMC / SPI Graphical TFT // Classic UI Options
// //
#if TFT_SCALED_DOGLCD #if TFT_SCALED_DOGLCD
//#define GRAPHICAL_TFT_ROTATE_180
//#define TFT_MARLINUI_COLOR 0xFFFF // White //#define TFT_MARLINUI_COLOR 0xFFFF // White
//#define TFT_MARLINBG_COLOR 0x0000 // Black //#define TFT_MARLINBG_COLOR 0x0000 // Black
//#define TFT_DISABLED_COLOR 0x0003 // Almost black //#define TFT_DISABLED_COLOR 0x0003 // Almost black
@ -3378,6 +3375,25 @@
//#define JOYSTICK_DEBUG //#define JOYSTICK_DEBUG
#endif #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 * MAX7219 Debug Matrix
* *

View file

@ -28,7 +28,7 @@
/** /**
* Marlin release version identifier * Marlin release version identifier
*/ */
//#define SHORT_BUILD_VERSION "2.0.7.1" //#define SHORT_BUILD_VERSION "2.0.7.2"
/** /**
* Verbose version identifier which should contain a reference to the location * Verbose version identifier which should contain a reference to the location

View file

@ -25,7 +25,7 @@
#include "watchdog.h" #include "watchdog.h"
#include "math.h" #include "math.h"
#ifdef USBCON #ifdef IS_AT90USB
#include <HardwareSerial.h> #include <HardwareSerial.h>
#else #else
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion #define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
@ -81,7 +81,7 @@ typedef int8_t pin_t;
//extern uint8_t MCUSR; //extern uint8_t MCUSR;
// Serial ports // Serial ports
#ifdef USBCON #ifdef IS_AT90USB
#define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial) #define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial)
#else #else
#if !WITHIN(SERIAL_PORT, -1, 3) #if !WITHIN(SERIAL_PORT, -1, 3)

View file

@ -38,7 +38,7 @@
#include "../../inc/MarlinConfig.h" #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 "MarlinSerial.h"
#include "../../MarlinCore.h" #include "../../MarlinCore.h"
@ -792,10 +792,10 @@ MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
#endif #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 // For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH) #if BOTH(IS_AT90USB, BLUETOOTH)
HardwareSerial bluetoothSerial; HardwareSerial bluetoothSerial;
#endif #endif

View file

@ -327,6 +327,6 @@
#endif #endif
// Use the UART for Bluetooth in AT90USB configurations // Use the UART for Bluetooth in AT90USB configurations
#if defined(USBCON) && ENABLED(BLUETOOTH) #if BOTH(IS_AT90USB, BLUETOOTH)
extern HardwareSerial bluetoothSerial; extern HardwareSerial bluetoothSerial;
#endif #endif

View file

@ -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) 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 if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed

View file

@ -34,7 +34,7 @@
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION) #define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
#ifndef I2C_ADDRESS #ifndef I2C_ADDRESS
#define I2C_ADDRESS(A) (A) #define I2C_ADDRESS(A) uint8_t(A)
#endif #endif
// Needed for AVR sprintf_P PROGMEM extension // Needed for AVR sprintf_P PROGMEM extension

View file

@ -24,10 +24,3 @@
#if HAS_FSMC_TFT #if HAS_FSMC_TFT
#error "Sorry! FSMC TFT displays are not current available for HAL/LPC1768." #error "Sorry! FSMC TFT displays are not current available for HAL/LPC1768."
#endif #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

View file

@ -191,7 +191,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
// //
// Flag any i2c pin conflicts // 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 #define USEDI2CDEV_M 1 // <Arduino>/Wire.cpp
#if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1) #if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1)

View file

@ -36,7 +36,7 @@
#define DATASIZE_8BIT SSP_DATABIT_8 #define DATASIZE_8BIT SSP_DATABIT_8
#define DATASIZE_16BIT SSP_DATABIT_16 #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_ENABLE 1
#define DMA_MINC_DISABLE 0 #define DMA_MINC_DISABLE 0

View file

@ -35,7 +35,8 @@
// MYSERIAL0 required before MarlinSerial includes! // 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)) #define MSERIAL(X) _MSERIAL(INCREMENT(X))
#if SERIAL_PORT == -1 #if SERIAL_PORT == -1

View file

@ -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) #if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32L0xx) || defined(STM32L4xx)
#define _WRITE(IO, V) do { \ #define _WRITE(IO, V) do { \
if (V) FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO])) ; \ if (V) FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \
else FastIOPortMap[STM_PORT(digitalPin[IO])]->BRR = _BV32(STM_PIN(digitalPin[IO])) ; \ else FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \
}while(0) }while(0)
#else #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 #endif
#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPin[IO])]->IDR, _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(digitalPin[IO])]->ODR ^= _BV32(STM_PIN(digitalPin[IO]))) #define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR ^= _BV32(STM_PIN(digitalPinToPinName(IO))))
#define _GET_MODE(IO) #define _GET_MODE(IO)
#define _SET_MODE(IO,M) pinMode(IO, M) #define _SET_MODE(IO,M) pinMode(IO, M)

View file

@ -51,8 +51,8 @@
* It contains: * It contains:
* - name of the signal * - name of the signal
* - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines. * - 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 * EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as the
* index into digitalPin[] to get the Port_pin number * argument to digitalPinToPinName(IO) to get the Port_pin number
* - if it is a digital or analog signal. PWMs are considered digital here. * - 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 * 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. * 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 // 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) { uint8_t get_pin_mode(const pin_t Ard_num) {
uint32_t mode_all = 0; uint32_t mode_all = 0;
const PinName dp = digitalPin[Ard_num]; const PinName dp = digitalPinToPinName(Ard_num);
switch (PORT_ALPHA(dp)) { switch (PORT_ALPHA(dp)) {
case 'A' : mode_all = GPIOA->MODER; break; case 'A' : mode_all = GPIOA->MODER; break;
case 'B' : mode_all = GPIOB->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) { void pwm_details(const pin_t Ard_num) {
if (pwm_status(Ard_num)) { if (pwm_status(Ard_num)) {
uint32_t alt_all = 0; 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)); pin_t pin_number = uint8_t(PIN_NUM(dp));
const bool over_7 = pin_number >= 8; const bool over_7 = pin_number >= 8;
const uint8_t ind = over_7 ? 1 : 0; const uint8_t ind = over_7 ? 1 : 0;

View file

@ -38,7 +38,7 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT #define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT #define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO TFT_FSMC #define TFT_IO_DRIVER TFT_FSMC
#ifdef STM32F1xx #ifdef STM32F1xx
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN) #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)

View file

@ -38,7 +38,7 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT #define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT #define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO TFT_SPI #define TFT_IO_DRIVER TFT_SPI
class TFT_SPI { class TFT_SPI {
private: private:

View file

@ -30,7 +30,11 @@
#include "watchdog.h" #include "watchdog.h"
#include <IWatchdog.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() { void HAL_watchdog_refresh() {
IWatchdog.reload(); IWatchdog.reload();

View file

@ -22,7 +22,6 @@
#if BOTH(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI) #if BOTH(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI)
#include "../HAL.h"
#include <U8glib.h> #include <U8glib.h>
#undef SPI_SPEED #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; return 1;
} }
#endif // HAS_MARLINUI_U8GLIB #endif // HAS_MARLINUI_U8GLIB && FORCE_SOFT_SPI
#endif // STM32F1 #endif // STM32F1

View file

@ -25,10 +25,3 @@
//#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE." //#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE."
#undef SD_CHECK_AND_RETRY #undef SD_CHECK_AND_RETRY
#endif #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

View file

@ -89,25 +89,12 @@ void TFT_FSMC::Init() {
uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN; uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN;
uint32_t controllerAddress; uint32_t controllerAddress;
#if PIN_EXISTS(TFT_BACKLIGHT)
OUT_WRITE(TFT_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT));
#endif
#if ENABLED(LCD_USE_DMA_FSMC) #if ENABLED(LCD_USE_DMA_FSMC)
dma_init(FSMC_DMA_DEV); dma_init(FSMC_DMA_DEV);
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM); dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM);
#endif #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; struct fsmc_nor_psram_reg_map* fsmcPsramRegion;
if (fsmcInit) return; if (fsmcInit) return;

View file

@ -32,7 +32,7 @@
#define DATASIZE_8BIT DMA_SIZE_8BITS #define DATASIZE_8BIT DMA_SIZE_8BITS
#define DATASIZE_16BIT DMA_SIZE_16BITS #define DATASIZE_16BIT DMA_SIZE_16BITS
#define TFT_IO TFT_FSMC #define TFT_IO_DRIVER TFT_FSMC
typedef struct { typedef struct {
__IO uint16_t REG; __IO uint16_t REG;

View file

@ -34,7 +34,7 @@
#define DATASIZE_8BIT DATA_SIZE_8BIT #define DATASIZE_8BIT DATA_SIZE_8BIT
#define DATASIZE_16BIT DATA_SIZE_16BIT #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_ENABLE 1
#define DMA_MINC_DISABLE 0 #define DMA_MINC_DISABLE 0

View file

@ -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) * @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() { 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 #endif // USE_WATCHDOG

View file

@ -85,7 +85,7 @@
#define START_FLASH_ADDR 0x08000000 #define START_FLASH_ADDR 0x08000000
#define END_FLASH_ADDR 0x08100000 #define END_FLASH_ADDR 0x08100000
#elif MB(REMRAM_V1) #elif MB(REMRAM_V1, NUCLEO_F767ZI)
// For STM32F765VI in RemRam v1 // For STM32F765VI in RemRam v1
// SRAM (0x20000000 - 0x20080000) (512kb) // SRAM (0x20000000 - 0x20080000) (512kb)

View file

@ -97,7 +97,7 @@
#include "feature/closedloop.h" #include "feature/closedloop.h"
#endif #endif
#if HAS_I2C_DIGIPOT #if HAS_MOTOR_CURRENT_I2C
#include "feature/digipot/digipot.h" #include "feature/digipot/digipot.h"
#endif #endif
@ -125,7 +125,7 @@
#include "module/servo.h" #include "module/servo.h"
#endif #endif
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
#include "feature/dac/stepper_dac.h" #include "feature/dac/stepper_dac.h"
#endif #endif
@ -1137,12 +1137,12 @@ void setup() {
SETUP_RUN(enableStepperDrivers()); SETUP_RUN(enableStepperDrivers());
#endif #endif
#if HAS_I2C_DIGIPOT #if HAS_MOTOR_CURRENT_I2C
SETUP_RUN(digipot_i2c_init()); SETUP_RUN(digipot_i2c.init());
#endif #endif
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
SETUP_RUN(dac_init()); SETUP_RUN(stepper_dac.init());
#endif #endif
#if EITHER(Z_PROBE_SLED, SOLENOID_PROBE) && HAS_SOLENOID_1 #if EITHER(Z_PROBE_SLED, SOLENOID_PROBE) && HAS_SOLENOID_1

View file

@ -363,6 +363,7 @@
#define BOARD_REMRAM_V1 5001 // RemRam v1 #define BOARD_REMRAM_V1 5001 // RemRam v1
#define BOARD_TEENSY41 5002 // Teensy 4.1 #define BOARD_TEENSY41 5002 // Teensy 4.1
#define BOARD_T41U5XBB 5003 // T41U5XBB Teensy 4.1 breakout board #define BOARD_T41U5XBB 5003 // T41U5XBB Teensy 4.1 breakout board
#define BOARD_NUCLEO_F767ZI 5004 // ST NUCLEO-F767ZI Dev Board
// //
// Espressif ESP32 WiFi // Espressif ESP32 WiFi

View file

@ -452,6 +452,12 @@
#define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)()) #define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)())
#define _END_OF_ARGUMENTS_() 0 #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. // REPEAT core macros. Recurse N times with ascending I.
// //

View file

@ -348,7 +348,7 @@ float bilinear_z_offset(const xy_pos_t &raw) {
* Prepare a bilinear-leveled linear move on Cartesian, * Prepare a bilinear-leveled linear move on Cartesian,
* splitting the move where it crosses grid borders. * splitting the move where it crosses grid borders.
*/ */
void bilinear_line_to_destination(const feedRate_t scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) { void bilinear_line_to_destination(const feedRate_t &scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) {
// Get current and destination cells for this line // Get current and destination cells for this line
xy_int_t c1 { CELL_INDEX(x, current_position.x), CELL_INDEX(y, current_position.y) }, xy_int_t c1 { CELL_INDEX(x, current_position.x), CELL_INDEX(y, current_position.y) },
c2 { CELL_INDEX(x, destination.x), CELL_INDEX(y, destination.y) }; c2 { CELL_INDEX(x, destination.x), CELL_INDEX(y, destination.y) };

View file

@ -1009,6 +1009,8 @@
lcd_mesh_edit_setup(new_z); lcd_mesh_edit_setup(new_z);
SET_SOFT_ENDSTOP_LOOSE(true);
do { do {
idle(); idle();
new_z = lcd_mesh_edit(); new_z = lcd_mesh_edit();
@ -1016,6 +1018,8 @@
SERIAL_FLUSH(); // Prevent host M105 buffer overrun. SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
} while (!ui.button_pressed()); } 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 (!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 if (click_and_hold(abort_fine_tune)) break; // Button held down? Abort editing

View file

@ -32,16 +32,18 @@
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
#include "dac_mcp4728.h" #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 * Begin I2C, get current values (input register and eeprom) of mcp4728
*/ */
void mcp4728_init() { void MCP4728::init() {
Wire.begin(); Wire.begin();
Wire.requestFrom(I2C_ADDRESS(DAC_DEV_ADDRESS), uint8_t(24)); Wire.requestFrom(I2C_ADDRESS(DAC_DEV_ADDRESS), uint8_t(24));
while (Wire.available()) { while (Wire.available()) {
@ -50,7 +52,7 @@ void mcp4728_init() {
loByte = Wire.read(); loByte = Wire.read();
if (!(deviceID & 0x08)) 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. * Write input resister value to specified channel using fastwrite method.
* Channel : 0-3, Values : 0-4095 * Channel : 0-3, Values : 0-4095
*/ */
uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) { uint8_t MCP4728::analogWrite(const uint8_t channel, const uint16_t value) {
mcp4728_values[channel] = value; dac_values[channel] = value;
return mcp4728_fastWrite(); 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 update both input register and EEPROM value
* This will also write current Vref, PowerDown, Gain settings to EEPROM * 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.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
Wire.write(SEQWRITE); Wire.write(SEQWRITE);
LOOP_XYZE(i) { LOOP_XYZE(i) {
Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[i])); Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(dac_values[i]));
Wire.write(lowByte(mcp4728_values[i])); Wire.write(lowByte(dac_values[i]));
} }
return Wire.endTransmission(); return Wire.endTransmission();
} }
@ -81,7 +83,7 @@ uint8_t mcp4728_eepromWrite() {
/** /**
* Write Voltage reference setting to all input regiters * 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.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
Wire.write(VREFWRITE | (value ? 0x0F : 0x00)); Wire.write(VREFWRITE | (value ? 0x0F : 0x00));
return Wire.endTransmission(); return Wire.endTransmission();
@ -89,7 +91,7 @@ uint8_t mcp4728_setVref_all(const uint8_t value) {
/** /**
* Write Gain setting to all input regiters * 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.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
Wire.write(GAINWRITE | (value ? 0x0F : 0x00)); Wire.write(GAINWRITE | (value ? 0x0F : 0x00));
return Wire.endTransmission(); return Wire.endTransmission();
@ -98,16 +100,16 @@ uint8_t mcp4728_setGain_all(const uint8_t value) {
/** /**
* Return Input Register 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 #if 0
/** /**
* Steph: Might be useful in the future * Steph: Might be useful in the future
* Return Vout * Return Vout
*/ */
uint16_t mcp4728_getVout(const uint8_t channel) { uint16_t MCP4728::getVout(const uint8_t channel) {
const uint32_t vref = 2048, 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); return _MIN(vOut, defaultVDD);
} }
#endif #endif
@ -115,15 +117,15 @@ uint16_t mcp4728_getVout(const uint8_t channel) {
/** /**
* Returns DAC values as a 0-100 percentage of drive strength * 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 * Receives all Drive strengths as 0-100 percent values, updates
* DAC Values array and calls fastwrite to update the DAC. * DAC Values array and calls fastwrite to update the DAC.
*/ */
void mcp4728_setDrvPct(xyze_uint8_t &pct) { void MCP4728::setDrvPct(xyze_uint8_t &pct) {
mcp4728_values *= 0.01 * pct * (DAC_STEPPER_MAX); dac_values *= 0.01 * pct * (DAC_STEPPER_MAX);
mcp4728_fastWrite(); fastWrite();
} }
/** /**
@ -131,11 +133,11 @@ void mcp4728_setDrvPct(xyze_uint8_t &pct) {
* DAC Input and PowerDown bits update. * DAC Input and PowerDown bits update.
* No EEPROM update * No EEPROM update
*/ */
uint8_t mcp4728_fastWrite() { uint8_t MCP4728::fastWrite() {
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS));
LOOP_XYZE(i) { LOOP_XYZE(i) {
Wire.write(highByte(mcp4728_values[i])); Wire.write(highByte(dac_values[i]));
Wire.write(lowByte(mcp4728_values[i])); Wire.write(lowByte(dac_values[i]));
} }
return Wire.endTransmission(); return Wire.endTransmission();
} }
@ -143,10 +145,10 @@ uint8_t mcp4728_fastWrite() {
/** /**
* Common function for simple general commands * 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.beginTransmission(I2C_ADDRESS(GENERALCALL));
Wire.write(simpleCommand); Wire.write(simpleCommand);
return Wire.endTransmission(); return Wire.endTransmission();
} }
#endif // DAC_STEPPER_CURRENT #endif // HAS_MOTOR_CURRENT_DAC

View file

@ -65,13 +65,18 @@
// DAC_OR_ADDRESS defined in pins_BOARD.h file // DAC_OR_ADDRESS defined in pins_BOARD.h file
#define DAC_DEV_ADDRESS (BASE_ADDR | DAC_OR_ADDRESS) #define DAC_DEV_ADDRESS (BASE_ADDR | DAC_OR_ADDRESS)
void mcp4728_init(); class MCP4728 {
uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value); public:
uint8_t mcp4728_eepromWrite(); static void init();
uint8_t mcp4728_setVref_all(const uint8_t value); static uint8_t analogWrite(const uint8_t channel, const uint16_t value);
uint8_t mcp4728_setGain_all(const uint8_t value); static uint8_t eepromWrite();
uint16_t mcp4728_getValue(const uint8_t channel); static uint8_t setVref_all(const uint8_t value);
uint8_t mcp4728_fastWrite(); static uint8_t setGain_all(const uint8_t value);
uint8_t mcp4728_simpleCommand(const byte simpleCommand); static uint16_t getValue(const uint8_t channel);
uint8_t mcp4728_getDrvPct(const uint8_t channel); static uint8_t fastWrite();
void mcp4728_setDrvPct(xyze_uint8_t &pct); 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;

View file

@ -26,7 +26,7 @@
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
#include "stepper_dac.h" #include "stepper_dac.h"
#include "../../MarlinCore.h" // for SP_X_LBL... #include "../../MarlinCore.h" // for SP_X_LBL...
@ -35,56 +35,53 @@ bool dac_present = false;
constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER; constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER;
xyze_uint8_t dac_channel_pct = DAC_MOTOR_CURRENT_DEFAULT; xyze_uint8_t dac_channel_pct = DAC_MOTOR_CURRENT_DEFAULT;
int dac_init() { StepperDAC stepper_dac;
int StepperDAC::init() {
#if PIN_EXISTS(DAC_DISABLE) #if PIN_EXISTS(DAC_DISABLE)
OUT_WRITE(DAC_DISABLE_PIN, LOW); // set pin low to enable DAC OUT_WRITE(DAC_DISABLE_PIN, LOW); // set pin low to enable DAC
#endif #endif
mcp4728_init(); mcp4728.init();
if (mcp4728_simpleCommand(RESET)) return -1; if (mcp4728.simpleCommand(RESET)) return -1;
dac_present = true; dac_present = true;
mcp4728_setVref_all(DAC_STEPPER_VREF); mcp4728.setVref_all(DAC_STEPPER_VREF);
mcp4728_setGain_all(DAC_STEPPER_GAIN); mcp4728.setGain_all(DAC_STEPPER_GAIN);
if (mcp4728_getDrvPct(0) < 1 || mcp4728_getDrvPct(1) < 1 || mcp4728_getDrvPct(2) < 1 || mcp4728_getDrvPct(3) < 1 ) { if (mcp4728.getDrvPct(0) < 1 || mcp4728.getDrvPct(1) < 1 || mcp4728.getDrvPct(2) < 1 || mcp4728.getDrvPct(3) < 1 ) {
mcp4728_setDrvPct(dac_channel_pct); mcp4728.setDrvPct(dac_channel_pct);
mcp4728_eepromWrite(); mcp4728.eepromWrite();
} }
return 0; return 0;
} }
void dac_current_percent(uint8_t channel, float val) { void StepperDAC::set_current_value(const uint8_t channel, uint16_t 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) {
if (!dac_present) return; if (!dac_present) return;
NOMORE(val, uint16_t(DAC_STEPPER_MAX)); NOMORE(val, uint16_t(DAC_STEPPER_MAX));
mcp4728_analogWrite(dac_order[channel], val); mcp4728.analogWrite(dac_order[channel], val);
mcp4728_simpleCommand(UPDATE); mcp4728.simpleCommand(UPDATE);
} }
static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) * RECIPROCAL(DAC_STEPPER_MAX); } void StepperDAC::set_current_percent(const uint8_t channel, float val) {
static float dac_amps(int8_t n) { return mcp4728_getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * RECIPROCAL(DAC_STEPPER_SENSE); } 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]); } static float dac_perc(int8_t n) { return 100.0 * mcp4728.getValue(dac_order[n]) * RECIPROCAL(DAC_STEPPER_MAX); }
void dac_current_set_percents(xyze_uint8_t &pct) { 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]]; 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; if (!dac_present) return;
SERIAL_ECHO_MSG("Stepper current values in % (Amps):"); SERIAL_ECHO_MSG("Stepper current values in % (Amps):");
SERIAL_ECHO_START(); 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(")")); 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; if (!dac_present) return;
mcp4728_eepromWrite(); mcp4728.eepromWrite();
} }
#endif // DAC_STEPPER_CURRENT #endif // HAS_MOTOR_CURRENT_DAC

View file

@ -27,10 +27,15 @@
#include "dac_mcp4728.h" #include "dac_mcp4728.h"
int dac_init(); class StepperDAC {
void dac_current_percent(uint8_t channel, float val); public:
void dac_current_raw(uint8_t channel, uint16_t val); static int init();
void dac_print_values(); static void set_current_percent(const uint8_t channel, float val);
void dac_commit_eeprom(); static void set_current_value(const uint8_t channel, uint16_t val);
uint8_t dac_current_get_percent(AxisEnum axis); static void print_values();
void dac_current_set_percents(xyze_uint8_t &pct); 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;

View file

@ -21,5 +21,13 @@
*/ */
#pragma once #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;

View file

@ -24,6 +24,8 @@
#if ENABLED(DIGIPOT_MCP4018) #if ENABLED(DIGIPOT_MCP4018)
#include "digipot.h"
#include <Stream.h> #include <Stream.h>
#include <SlowSoftI2CMaster.h> // https://github.com/stawel/SlowSoftI2CMaster #include <SlowSoftI2CMaster.h> // https://github.com/stawel/SlowSoftI2CMaster
@ -68,7 +70,7 @@ static SlowSoftI2CMaster pots[DIGIPOT_I2C_NUM_CHANNELS] = {
#endif #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)) { if (WITHIN(channel, 0, DIGIPOT_I2C_NUM_CHANNELS - 1)) {
pots[channel].i2c_start(((DIGIPOT_I2C_ADDRESS_A) << 1) | I2C_WRITE); pots[channel].i2c_start(((DIGIPOT_I2C_ADDRESS_A) << 1) | I2C_WRITE);
pots[channel].i2c_write(v); 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 // 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)); 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(); LOOP_L_N(i, DIGIPOT_I2C_NUM_CHANNELS) pots[i].i2c_init();
// Init currents according to Configuration_adv.h // Init currents according to Configuration_adv.h
@ -94,7 +96,7 @@ void digipot_i2c_init() {
#endif #endif
; ;
LOOP_L_N(i, COUNT(digipot_motor_current)) 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 #endif // DIGIPOT_MCP4018

View file

@ -24,6 +24,8 @@
#if ENABLED(DIGIPOT_MCP4451) #if ENABLED(DIGIPOT_MCP4451)
#include "digipot.h"
#include <Stream.h> #include <Stream.h>
#include <Wire.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 // 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. // 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 // 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 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))); 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) #if MB(MKS_SBASE)
configure_i2c(16); // Set clock_option to 16 ensure I2C is initialized at 400kHz configure_i2c(16); // Set clock_option to 16 ensure I2C is initialized at 400kHz
#else #else
@ -90,7 +92,7 @@ void digipot_i2c_init() {
#endif #endif
; ;
LOOP_L_N(i, COUNT(digipot_motor_current)) 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 #endif // DIGIPOT_MCP4451

View file

@ -61,6 +61,10 @@
#include "../libs/buzzer.h" #include "../libs/buzzer.h"
#endif #endif
#if ENABLED(POWER_LOSS_RECOVERY)
#include "powerloss.h"
#endif
#include "../libs/nozzle.h" #include "../libs/nozzle.h"
#include "pause.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 // Set extruder to saved position
planner.set_e_position_mm((destination.e = current_position.e = resume_position.e)); 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)); TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS));
#ifdef ACTION_ON_RESUMED #ifdef ACTION_ON_RESUMED

View file

@ -511,11 +511,9 @@ void GcodeSuite::G26() {
g26_keep_heaters_on = parser.boolval('K'); g26_keep_heaters_on = parser.boolval('K');
// Accept 'I' if temperature presets are defined // Accept 'I' if temperature presets are defined
const uint8_t preset_index = (0
#if PREHEAT_COUNT #if PREHEAT_COUNT
+ (parser.seenval('I') ? _MIN(parser.value_byte(), PREHEAT_COUNT - 1) + 1 : 0) const uint8_t preset_index = parser.seenval('I') ? _MIN(parser.value_byte(), PREHEAT_COUNT - 1) + 1 : 0;
#endif #endif
);
#if HAS_HEATED_BED #if HAS_HEATED_BED

View file

@ -160,6 +160,7 @@ void GcodeSuite::G35() {
" ", (screw_thread & 1) == (adjust > 0) ? "CCW" : "CW", " ", (screw_thread & 1) == (adjust > 0) ? "CCW" : "CW",
" by ", abs(full_turns), " turns"); " by ", abs(full_turns), " turns");
if (minutes) SERIAL_ECHOPAIR(" and ", abs(minutes), " minutes"); if (minutes) SERIAL_ECHOPAIR(" and ", abs(minutes), " minutes");
if (ENABLED(REPORT_TRAMMING_MM)) SERIAL_ECHOPAIR(" (", -diff, "mm)");
SERIAL_EOL(); SERIAL_EOL();
} }
} }

View file

@ -201,10 +201,6 @@ G29_TYPE GcodeSuite::G29() {
ABL_VAR int abl_probe_index; ABL_VAR int abl_probe_index;
#endif #endif
#if BOTH(HAS_SOFTWARE_ENDSTOPS, PROBE_MANUALLY)
ABL_VAR bool saved_soft_endstops_state = true;
#endif
#if ABL_GRID #if ABL_GRID
#if ENABLED(PROBE_MANUALLY) #if ENABLED(PROBE_MANUALLY)
@ -461,7 +457,7 @@ G29_TYPE GcodeSuite::G29() {
// Abort current G29 procedure, go back to idle state // Abort current G29 procedure, go back to idle state
if (seenA && g29_in_progress) { if (seenA && g29_in_progress) {
SERIAL_ECHOLNPGM("Manual G29 aborted"); 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); set_bed_leveling_enabled(abl_should_enable);
g29_in_progress = false; g29_in_progress = false;
TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); TERN_(LCD_BED_LEVELING, ui.wait_for_move = false);
@ -482,7 +478,7 @@ G29_TYPE GcodeSuite::G29() {
if (abl_probe_index == 0) { if (abl_probe_index == 0) {
// For the initial G29 S2 save software endstop state // 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 // Move close to the bed before the first point
do_blocking_move_to_z(0); do_blocking_move_to_z(0);
} }
@ -552,14 +548,14 @@ G29_TYPE GcodeSuite::G29() {
_manual_goto_xy(probePos); // Can be used here too! _manual_goto_xy(probePos); // Can be used here too!
// Disable software endstops to allow manual adjustment // Disable software endstops to allow manual adjustment
// If G29 is not completed, they will not be re-enabled // 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); G29_RETURN(false);
} }
else { else {
// Leveling done! Fall through to G29 finishing code below // Leveling done! Fall through to G29 finishing code below
SERIAL_ECHOLNPGM("Grid probing done."); SERIAL_ECHOLNPGM("Grid probing done.");
// Re-enable software endstops, if needed // 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) #elif ENABLED(AUTO_BED_LEVELING_3POINT)
@ -570,7 +566,7 @@ G29_TYPE GcodeSuite::G29() {
_manual_goto_xy(probePos); _manual_goto_xy(probePos);
// Disable software endstops to allow manual adjustment // Disable software endstops to allow manual adjustment
// If G29 is not completed, they will not be re-enabled // 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); G29_RETURN(false);
} }
else { else {
@ -578,7 +574,7 @@ G29_TYPE GcodeSuite::G29() {
SERIAL_ECHOLNPGM("3-point probing done."); SERIAL_ECHOLNPGM("3-point probing done.");
// Re-enable software endstops, if needed // Re-enable software endstops, if needed
TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstops_enabled = saved_soft_endstops_state); SET_SOFT_ENDSTOP_LOOSE(false);
if (!dryrun) { if (!dryrun) {
vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal(); vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal();

View file

@ -61,7 +61,6 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM("
void GcodeSuite::G29() { void GcodeSuite::G29() {
static int mbl_probe_index = -1; 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); MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
if (!WITHIN(state, 0, 5)) { if (!WITHIN(state, 0, 5)) {
@ -98,26 +97,19 @@ void GcodeSuite::G29() {
} }
// For each G29 S2... // For each G29 S2...
if (mbl_probe_index == 0) { 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 // Move close to the bed before the first point
do_blocking_move_to_z(0); do_blocking_move_to_z(0);
} }
else { else {
// Save Z for the previous mesh position // Save Z for the previous mesh position
mbl.set_zigzag_z(mbl_probe_index - 1, current_position.z); 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 there's another point to sample, move there with optional lift.
if (mbl_probe_index < GRID_MAX_POINTS) { if (mbl_probe_index < GRID_MAX_POINTS) {
#if HAS_SOFTWARE_ENDSTOPS
// Disable software endstops to allow manual adjustment // Disable software endstops to allow manual adjustment
// If G29 is not completed, they will not be re-enabled // If G29 is left hanging without completion they won't be re-enabled!
soft_endstops_enabled = false; SET_SOFT_ENDSTOP_LOOSE(true);
#endif
mbl.zigzag(mbl_probe_index++, ix, iy); mbl.zigzag(mbl_probe_index++, ix, iy);
_manual_goto_xy({ mbl.index_to_xpos[ix], mbl.index_to_ypos[iy] }); _manual_goto_xy({ mbl.index_to_xpos[ix], mbl.index_to_ypos[iy] });
} }

View file

@ -222,8 +222,9 @@ void GcodeSuite::G28() {
return; return;
} }
// Wait for planner moves to finish! planner.synchronize(); // Wait for planner moves to finish!
planner.synchronize();
SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state
// Disable the leveling matrix before homing // Disable the leveling matrix before homing
#if HAS_LEVELING #if HAS_LEVELING

View 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

View file

@ -20,26 +20,27 @@
* *
*/ */
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfigPre.h"
#if ENABLED(Z_STEPPER_AUTO_ALIGN) #if ENABLED(Z_STEPPER_AUTO_ALIGN)
#include "../../feature/z_stepper_align.h" #include "../../feature/z_stepper_align.h"
#include "../gcode.h" #include "../gcode.h"
#include "../../module/planner.h"
#include "../../module/stepper.h"
#include "../../module/motion.h" #include "../../module/motion.h"
#include "../../module/stepper.h"
#include "../../module/planner.h"
#include "../../module/probe.h" #include "../../module/probe.h"
#include "../../lcd/ultralcd.h" // for LCD_MESSAGEPGM
#if HAS_MULTI_HOTEND
#include "../../module/tool_change.h"
#endif
#if HAS_LEVELING #if HAS_LEVELING
#include "../../feature/bedlevel/bedlevel.h" #include "../../feature/bedlevel/bedlevel.h"
#endif #endif
#if HAS_MULTI_HOTEND
#include "../../module/tool_change.h"
#endif
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
#include "../../libs/least_squares_fit.h" #include "../../libs/least_squares_fit.h"
#endif #endif
@ -117,7 +118,7 @@ void GcodeSuite::G34() {
// In BLTOUCH HS mode, the probe travels in a deployed state. // 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 // Users of G34 might have a badly misaligned bed, so raise Z by the
// length of the deployed pin (BLTOUCH stroke < 7mm) // 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 // Compute a worst-case clearance height to probe from. After the first
// iteration this will be re-calculated based on the actual bed position // iteration this will be re-calculated based on the actual bed position
@ -154,21 +155,29 @@ void GcodeSuite::G34() {
z_maxdiff = 0.0f, z_maxdiff = 0.0f,
amplification = z_auto_align_amplification; 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) #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
bool adjustment_reverse = false; bool adjustment_reverse = false;
#endif #endif
// 'iteration' is declared above and is also used after the for-loop. #if HAS_DISPLAY
// *not* the same as LOOP_L_N(iteration, z_auto_align_iterations) PGM_P const msg_iteration = GET_TEXT(MSG_ITERATION);
for (iteration = 0; iteration < z_auto_align_iterations; ++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."); 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 // Initialize minimum value
z_measured_min = 100000.0f; z_measured_min = 100000.0f;
@ -190,7 +199,8 @@ void GcodeSuite::G34() {
// current_position.z has been manually altered in the "dirty trick" above. // 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); const float z_probed_height = probe.probe_at_point(z_stepper_align.xy[iprobe], raise_after, 0, true, false);
if (isnan(z_probed_height)) { if (isnan(z_probed_height)) {
SERIAL_ECHOLNPGM("Probing failed."); SERIAL_ECHOLNPGM("Probing failed");
LCD_MESSAGEPGM(MSG_LCD_PROBING_FAILED);
err_break = true; err_break = true;
break; break;
} }
@ -249,8 +259,39 @@ void GcodeSuite::G34() {
, " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) , " Z3-Z1=", ABS(z_measured[2] - z_measured[0])
#endif #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) #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
// Check if the applied corrections go in the correct direction. // Check if the applied corrections go in the correct direction.
// Calculate the sum of the absolute deviations from the mean of the probe measurements. // 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. // 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); z_align_level_indicator += ABS(z_measured[zstepper] - z_measured_mean);
// If it's getting worse, stop and throw an error // If it's getting worse, stop and throw an error
if (last_z_align_level_indicator < z_align_level_indicator * 0.7f) { err_break = decreasing_accuracy(last_z_align_level_indicator, z_align_level_indicator);
SERIAL_ECHOLNPGM("Decreasing accuracy detected."); if (err_break) break;
err_break = true;
break;
}
last_z_align_level_indicator = z_align_level_indicator; last_z_align_level_indicator = z_align_level_indicator;
#endif #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; 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 // Check for less accuracy compared to last move
if (last_z_align_move[zstepper] < z_align_abs * 0.7f) { if (decreasing_accuracy(last_z_align_move[zstepper], z_align_abs)) {
SERIAL_ECHOLNPGM("Decreasing accuracy detected.");
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), " last_z_align_move = ", last_z_align_move[zstepper]);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " z_align_abs = ", z_align_abs); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " z_align_abs = ", z_align_abs);
adjustment_reverse = !adjustment_reverse; adjustment_reverse = !adjustment_reverse;
@ -329,9 +366,14 @@ void GcodeSuite::G34() {
if (err_break) break; 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) if (err_break)
SERIAL_ECHOLNPGM("G34 aborted."); SERIAL_ECHOLNPGM("G34 aborted.");

View file

@ -581,13 +581,12 @@ void GcodeSuite::G425() {
GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_PRE)); GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_PRE));
#endif #endif
TEMPORARY_SOFT_ENDSTOP_STATE(false);
TEMPORARY_BED_LEVELING_STATE(false);
if (homing_needed_error()) return; 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; float uncertainty = parser.seenval('U') ? parser.value_float() : CALIBRATION_MEASUREMENT_UNCERTAIN;
if (parser.seen('B')) if (parser.seen('B'))
@ -612,6 +611,8 @@ void GcodeSuite::G425() {
else else
calibrate_all(); calibrate_all();
SET_SOFT_ENDSTOP_LOOSE(false);
#ifdef CALIBRATION_SCRIPT_POST #ifdef CALIBRATION_SCRIPT_POST
GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_POST)); GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_POST));
#endif #endif

View file

@ -46,6 +46,10 @@
#include "../../lcd/extui/ui_api.h" #include "../../lcd/extui/ui_api.h"
#endif #endif
#if HAS_RESUME_CONTINUE
#include "../../lcd/ultralcd.h"
#endif
#ifndef GET_PIN_MAP_PIN_M43 #ifndef GET_PIN_MAP_PIN_M43
#define GET_PIN_MAP_PIN_M43(Q) GET_PIN_MAP_PIN(Q) #define GET_PIN_MAP_PIN_M43(Q) GET_PIN_MAP_PIN(Q)
#endif #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); safe_delay(200);
} }

View file

@ -55,7 +55,7 @@ void GcodeSuite::M111() {
} }
else { else {
SERIAL_ECHOPGM(STR_DEBUG_OFF); SERIAL_ECHOPGM(STR_DEBUG_OFF);
#if !defined(__AVR__) || !defined(USBCON) #if !IS_AT90USB
#if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
SERIAL_ECHOPAIR("\nBuffer Overruns: ", MYSERIAL0.buffer_overruns()); SERIAL_ECHOPAIR("\nBuffer Overruns: ", MYSERIAL0.buffer_overruns());
#endif #endif
@ -71,7 +71,7 @@ void GcodeSuite::M111() {
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
SERIAL_ECHOPAIR("\nMax RX Queue Size: ", MYSERIAL0.rxMaxEnqueued()); SERIAL_ECHOPAIR("\nMax RX Queue Size: ", MYSERIAL0.rxMaxEnqueued());
#endif #endif
#endif // !defined(__AVR__) || !defined(USBCON) #endif // !IS_AT90USB
} }
SERIAL_EOL(); SERIAL_EOL();
} }

View file

@ -37,8 +37,8 @@ void GcodeSuite::M211() {
l_soft_max = soft_endstop.max.asLogical(); l_soft_max = soft_endstop.max.asLogical();
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPGM(STR_SOFT_ENDSTOPS); SERIAL_ECHOPGM(STR_SOFT_ENDSTOPS);
if (parser.seen('S')) soft_endstops_enabled = parser.value_bool(); if (parser.seen('S')) soft_endstop._enabled = parser.value_bool();
serialprint_onoff(soft_endstops_enabled); serialprint_onoff(soft_endstop._enabled);
print_xyz(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" ")); print_xyz(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" "));
print_xyz(l_soft_max, PSTR(STR_SOFT_MAX)); print_xyz(l_soft_max, PSTR(STR_SOFT_MAX));
} }

View file

@ -70,9 +70,11 @@ void GcodeSuite::G12() {
TEMPORARY_BED_LEVELING_STATE(!TEST(cleans, Z_AXIS) && planner.leveling_active); TEMPORARY_BED_LEVELING_STATE(!TEST(cleans, Z_AXIS) && planner.leveling_active);
#endif #endif
TEMPORARY_SOFT_ENDSTOP_STATE(parser.boolval('E')); SET_SOFT_ENDSTOP_LOOSE(!parser.boolval('E'));
nozzle.clean(pattern, strokes, radius, objects, cleans); nozzle.clean(pattern, strokes, radius, objects, cleans);
SET_SOFT_ENDSTOP_LOOSE(false);
} }
#endif // NOZZLE_CLEAN_FEATURE #endif // NOZZLE_CLEAN_FEATURE

View file

@ -22,19 +22,19 @@
#include "../../../inc/MarlinConfig.h" #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" #include "../../gcode.h"
#if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
#include "../../../module/stepper.h" #include "../../../module/stepper.h"
#endif #endif
#if HAS_I2C_DIGIPOT #if HAS_MOTOR_CURRENT_I2C
#include "../../../feature/digipot/digipot.h" #include "../../../feature/digipot/digipot.h"
#endif #endif
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
#include "../../../feature/dac/stepper_dac.h" #include "../../../feature/dac/stepper_dac.h"
#endif #endif
@ -42,61 +42,61 @@
* M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S
*/ */
void GcodeSuite::M907() { 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()); LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.set_digipot_current(i, parser.value_int());
if (parser.seenval('B')) stepper.digipot_current(4, 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.digipot_current(i, 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 #elif HAS_MOTOR_CURRENT_PWM
#if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY) #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 #endif
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) #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 #endif
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E) #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
#endif #endif
#if HAS_I2C_DIGIPOT #if HAS_MOTOR_CURRENT_I2C
// this one uses actual amps in floating point // 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. // Additional extruders use B,C,D for channels 4,5,6.
// TODO: Change these parameters because 'E' is used. B<index>? // TODO: Change these parameters because 'E' is used. B<index>?
for (uint8_t i = E_AXIS + 1; i < DIGIPOT_I2C_NUM_CHANNELS; i++) 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 #endif
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
if (parser.seenval('S')) { if (parser.seenval('S')) {
const float dac_percent = parser.value_float(); 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 #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>) * M908: Control digital trimpot directly (M908 P<pin> S<current>)
*/ */
void GcodeSuite::M908() { void GcodeSuite::M908() {
TERN_(HAS_DIGIPOTSS, stepper.digitalPotWrite(parser.intval('P'), parser.intval('S'))); TERN_(HAS_MOTOR_CURRENT_SPI, stepper.set_digipot_value_spi(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_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(); } #endif // HAS_MOTOR_CURRENT_DAC
void GcodeSuite::M910() { dac_commit_eeprom(); }
#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

View file

@ -327,7 +327,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 33: G33(); break; // G33: Delta Auto-Calibration case 33: G33(); break; // G33: Delta Auto-Calibration
#endif #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 case 34: G34(); break; // G34: Z Stepper automatic alignment using probe
#endif #endif
@ -823,11 +823,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 900: M900(); break; // M900: Set advance K factor. case 900: M900(); break; // M900: Set advance K factor.
#endif #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. 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. 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 909: M909(); break; // M909: Print digipot/DAC current value
case 910: M910(); break; // M910: Commit digipot/DAC value to external EEPROM case 910: M910(); break; // M910: Commit digipot/DAC value to external EEPROM
#endif #endif

View file

@ -258,9 +258,9 @@
* M900 - Get or Set Linear Advance K-factor. (Requires LIN_ADVANCE) * 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) * 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) * 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) * M908 - Control digital trimpot directly. (Requires HAS_MOTOR_CURRENT_DAC or DIGIPOTSS_PIN)
* M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT) * M909 - Print digipot/DAC current value. (Requires HAS_MOTOR_CURRENT_DAC)
* M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT) * 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) * 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) * 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) * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD)
@ -465,11 +465,12 @@ private:
TERN_(DELTA_AUTO_CALIBRATION, static void G33()); 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 G34();
static void M422();
#endif #endif
TERN_(Z_STEPPER_AUTO_ALIGN, static void M422());
TERN_(ASSISTED_TRAMMING, static void G35()); TERN_(ASSISTED_TRAMMING, static void G35());
TERN_(G38_PROBE_TARGET, static void G38(const int8_t subcode)); TERN_(G38_PROBE_TARGET, static void G38(const int8_t subcode));
@ -847,11 +848,11 @@ private:
static void M918(); static void M918();
#endif #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(); static void M907();
#if EITHER(HAS_DIGIPOTSS, DAC_STEPPER_CURRENT) #if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
static void M908(); static void M908();
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
static void M909(); static void M909();
static void M910(); static void M910();
#endif #endif

View file

@ -25,8 +25,10 @@
#include "gcode.h" #include "gcode.h"
#include "../module/settings.h" #include "../module/settings.h"
#include "../module/temperature.h"
#include "../libs/hex_print.h" #include "../libs/hex_print.h"
#include "../HAL/shared/eeprom_if.h" #include "../HAL/shared/eeprom_if.h"
#include "../HAL/shared/Delay.h"
/** /**
* Dn: G-code for development and testing * Dn: G-code for development and testing
@ -84,6 +86,7 @@
} }
} break; } break;
#if ENABLED(EEPROM_SETTINGS)
case 3: { // D3 Read / Write EEPROM case 3: { // D3 Read / Write EEPROM
uint8_t *pointer = parser.hex_adr_val('A'); uint8_t *pointer = parser.hex_adr_val('A');
uint16_t len = parser.ushortval('C', 1); uint16_t len = parser.ushortval('C', 1);
@ -128,6 +131,7 @@
SERIAL_EOL(); SERIAL_EOL();
} }
} break; } break;
#endif
case 4: { // D4 Read / Write PIN case 4: { // D4 Read / Write PIN
// const uint8_t pin = parser.byteval('P'); // const uint8_t pin = parser.byteval('P');
@ -167,6 +171,20 @@
SERIAL_EOL(); SERIAL_EOL();
} }
} break; } 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.");
}
} }
} }

View file

@ -127,7 +127,7 @@ void GcodeSuite::M290() {
#else #else
PSTR("Babystep Z") PSTR("Babystep Z")
#endif #endif
, babystep.axis_total[BS_AXIS_IND(Z_AXIS)] , babystep.axis_total[BS_TOTAL_IND(Z_AXIS)]
); );
} }
#endif #endif

View file

@ -624,7 +624,7 @@ void GCodeQueue::advance() {
card.closefile(); card.closefile();
SERIAL_ECHOLNPGM(STR_FILE_SAVED); SERIAL_ECHOLNPGM(STR_FILE_SAVED);
#if !defined(__AVR__) || !defined(USBCON) #if !IS_AT90USB
#if ENABLED(SERIAL_STATS_DROPPED_RX) #if ENABLED(SERIAL_STATS_DROPPED_RX)
SERIAL_ECHOLNPAIR("Dropped bytes: ", MYSERIAL0.dropped()); SERIAL_ECHOLNPAIR("Dropped bytes: ", MYSERIAL0.dropped());
#endif #endif

View file

@ -63,12 +63,12 @@
#elif ENABLED(CARTESIO_UI) #elif ENABLED(CARTESIO_UI)
#define DOGLCD #define DOGLCD
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#elif EITHER(DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) #elif EITHER(DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE)
#define IS_DWIN_MARLINUI 1 #define IS_DWIN_MARLINUI 1
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#elif ENABLED(ZONESTAR_LCD) #elif ENABLED(ZONESTAR_LCD)
@ -76,7 +76,7 @@
#define IS_RRW_KEYPAD #define IS_RRW_KEYPAD
#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 #define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0
#define ADC_KEY_NUM 8 #define ADC_KEY_NUM 8
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
// This helps to implement ADC_KEYPAD menus // This helps to implement ADC_KEYPAD menus
#define REVERSE_MENU_DIRECTION #define REVERSE_MENU_DIRECTION
@ -98,7 +98,7 @@
#define IS_U8GLIB_SSD1306 #define IS_U8GLIB_SSD1306
#elif ENABLED(RADDS_DISPLAY) #elif ENABLED(RADDS_DISPLAY)
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#define ENCODER_PULSES_PER_STEP 2 #define ENCODER_PULSES_PER_STEP 2
#elif EITHER(ANET_FULL_GRAPHICS_LCD, BQ_LCD_SMART_CONTROLLER) #elif EITHER(ANET_FULL_GRAPHICS_LCD, BQ_LCD_SMART_CONTROLLER)
@ -108,7 +108,7 @@
#elif ANY(miniVIKI, VIKI2, ELB_FULL_GRAPHIC_CONTROLLER, AZSMZ_12864) #elif ANY(miniVIKI, VIKI2, ELB_FULL_GRAPHIC_CONTROLLER, AZSMZ_12864)
#define DOGLCD #define DOGLCD
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#if ENABLED(miniVIKI) #if ENABLED(miniVIKI)
#define U8GLIB_ST7565_64128N #define U8GLIB_ST7565_64128N
@ -123,19 +123,19 @@
#elif ENABLED(OLED_PANEL_TINYBOY2) #elif ENABLED(OLED_PANEL_TINYBOY2)
#define IS_U8GLIB_SSD1306 #define IS_U8GLIB_SSD1306
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#elif ENABLED(RA_CONTROL_PANEL) #elif ENABLED(RA_CONTROL_PANEL)
#define LCD_I2C_TYPE_PCA8574 #define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
#define DOGLCD #define DOGLCD
#define U8GLIB_ST7920 #define U8GLIB_ST7920
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#elif ENABLED(CR10_STOCKDISPLAY) #elif ENABLED(CR10_STOCKDISPLAY)
@ -179,7 +179,7 @@
#define FYSETC_MINI_12864 #define FYSETC_MINI_12864
#define DOGLCD #define DOGLCD
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#define LED_COLORS_REDUCE_GREEN #define LED_COLORS_REDUCE_GREEN
#if ENABLED(PSU_CONTROL) && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) #if ENABLED(PSU_CONTROL) && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1)
#define LED_BACKLIGHT_TIMEOUT 10000 #define LED_BACKLIGHT_TIMEOUT 10000
@ -205,7 +205,7 @@
#elif ENABLED(ULTI_CONTROLLER) #elif ENABLED(ULTI_CONTROLLER)
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#define U8GLIB_SSD1309 #define U8GLIB_SSD1309
#define LCD_RESET_PIN LCD_PINS_D6 // This controller need a reset pin #define LCD_RESET_PIN LCD_PINS_D6 // This controller need a reset pin
#define ENCODER_PULSES_PER_STEP 2 #define ENCODER_PULSES_PER_STEP 2
@ -220,7 +220,7 @@
#elif EITHER(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C) #elif EITHER(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C)
#define IS_TFTGLCD_PANEL 1 #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) #if ENABLED(SDSUPPORT) && DISABLED(LCD_PROGRESS_BAR)
#define LCD_PROGRESS_BAR #define LCD_PROGRESS_BAR
@ -246,7 +246,7 @@
#endif #endif
#if EITHER(MAKRPANEL, MINIPANEL) #if EITHER(MAKRPANEL, MINIPANEL)
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#define DOGLCD #define DOGLCD
#if ENABLED(MAKRPANEL) #if ENABLED(MAKRPANEL)
#define U8GLIB_ST7565_64128N #define U8GLIB_ST7565_64128N
@ -258,7 +258,7 @@
#endif #endif
#if ENABLED(OVERLORD_OLED) #if ENABLED(OVERLORD_OLED)
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#define U8GLIB_SH1106 #define U8GLIB_SH1106
/** /**
* PCA9632 for buzzer and LEDs via i2c * PCA9632 for buzzer and LEDs via i2c
@ -302,53 +302,64 @@
// Basic Ultipanel-like displays // Basic Ultipanel-like displays
#if ANY(ULTIMAKERCONTROLLER, REPRAP_DISCOUNT_SMART_CONTROLLER, G3D_PANEL, RIGIDBOT_PANEL, PANEL_ONE, U8GLIB_SH1106) #if ANY(ULTIMAKERCONTROLLER, REPRAP_DISCOUNT_SMART_CONTROLLER, G3D_PANEL, RIGIDBOT_PANEL, PANEL_ONE, U8GLIB_SH1106)
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#endif #endif
// Einstart OLED has Cardinal nav via pins defined in pins_EINSTART-S.h // Einstart OLED has Cardinal nav via pins defined in pins_EINSTART-S.h
#if ENABLED(U8GLIB_SH1106_EINSTART) #if ENABLED(U8GLIB_SH1106_EINSTART)
#define DOGLCD #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 #endif
// FSMC/SPI TFT Panels (LVGL) // 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 #define HAS_TFT_LVGL_UI 1
#endif #endif
// FSMC/SPI TFT Panels // FSMC/SPI TFT Panels
#if EITHER(FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT) #if ENABLED(TFT_CLASSIC_UI)
#define TFT_SCALED_DOGLCD 1 #define TFT_SCALED_DOGLCD 1
#endif #endif
#if TFT_SCALED_DOGLCD #if TFT_SCALED_DOGLCD
#define DOGLCD #define DOGLCD
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#define DELAYED_BACKLIGHT_INIT #define DELAYED_BACKLIGHT_INIT
#elif ENABLED(TFT_LVGL_UI_SPI) #elif ENABLED(TFT_LVGL_UI)
#define DELAYED_BACKLIGHT_INIT #define DELAYED_BACKLIGHT_INIT
#endif #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 // 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 HAS_GRAPHICAL_TFT 1
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#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 #endif
/** /**
@ -372,7 +383,7 @@
#define LCD_I2C_TYPE_MCP23017 #define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander #define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (optional) #define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (optional)
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#elif ENABLED(LCD_I2C_VIKI) #elif ENABLED(LCD_I2C_VIKI)
@ -387,7 +398,7 @@
#define LCD_I2C_TYPE_MCP23017 #define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander #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 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 #define ENCODER_FEEDRATE_DEADZONE 4
@ -432,10 +443,10 @@
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
#if ENABLED(FF_INTERFACEBOARD) #if ENABLED(FF_INTERFACEBOARD)
#define SR_LCD_3W_NL // Non latching 3 wire shift register #define SR_LCD_3W_NL // Non latching 3 wire shift register
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#elif ENABLED(SAV_3DLCD) #elif ENABLED(SAV_3DLCD)
#define SR_LCD_2W_NL // Non latching 2 wire shift register #define SR_LCD_2W_NL // Non latching 2 wire shift register
#define IS_ULTIPANEL #define IS_ULTIPANEL 1
#endif #endif
#if ENABLED(IS_ULTIPANEL) #if ENABLED(IS_ULTIPANEL)
@ -810,3 +821,128 @@
#ifndef EXTRUDE_MINTEMP #ifndef EXTRUDE_MINTEMP
#define EXTRUDE_MINTEMP 170 #define EXTRUDE_MINTEMP 170
#endif #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

View file

@ -175,7 +175,7 @@
#endif #endif
#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451) #if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
#define HAS_I2C_DIGIPOT 1 #define HAS_MOTOR_CURRENT_I2C 1
#endif #endif
// Multiple Z steppers // Multiple Z steppers
@ -208,7 +208,10 @@
#define NEEDS_HARDWARE_PWM 1 #define NEEDS_HARDWARE_PWM 1
#endif #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. // Define constants and variables for buffering serial data.
// Use only 0 or powers of 2 greater than 1 // Use only 0 or powers of 2 greater than 1
// : [0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...] // : [0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...]
@ -220,9 +223,6 @@
#ifndef TX_BUFFER_SIZE #ifndef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 32 #define TX_BUFFER_SIZE 32
#endif #endif
#else
// SERIAL_XON_XOFF not supported on USB-native devices
#undef SERIAL_XON_XOFF
#endif #endif
#if ENABLED(HOST_ACTION_COMMANDS) #if ENABLED(HOST_ACTION_COMMANDS)

View file

@ -1976,7 +1976,7 @@
#define HAS_STEPPER_RESET 1 #define HAS_STEPPER_RESET 1
#endif #endif
#if PIN_EXISTS(DIGIPOTSS) #if PIN_EXISTS(DIGIPOTSS)
#define HAS_DIGIPOTSS 1 #define HAS_MOTOR_CURRENT_SPI 1
#endif #endif
#if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_Z, MOTOR_CURRENT_PWM_E) #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 #define HAS_MOTOR_CURRENT_PWM 1

View file

@ -422,7 +422,7 @@
#elif defined(CHAMBER_HEATER_PIN) #elif defined(CHAMBER_HEATER_PIN)
#error "CHAMBER_HEATER_PIN is now HEATER_CHAMBER_PIN. Please update your configuration and/or pins." #error "CHAMBER_HEATER_PIN is now HEATER_CHAMBER_PIN. Please update your configuration and/or pins."
#elif defined(TMC_Z_CALIBRATION) #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) #elif defined(Z_MIN_PROBE_ENDSTOP)
#error "Z_MIN_PROBE_ENDSTOP is no longer required. Please remove it from Configuration.h." #error "Z_MIN_PROBE_ENDSTOP is no longer required. Please remove it from Configuration.h."
#elif defined(DUAL_NOZZLE_DUPLICATION_MODE) #elif defined(DUAL_NOZZLE_DUPLICATION_MODE)
@ -447,8 +447,6 @@
#error "POWER_SUPPLY is now obsolete. Please remove it from Configuration.h." #error "POWER_SUPPLY is now obsolete. Please remove it from Configuration.h."
#elif defined(MKS_ROBIN_TFT) #elif defined(MKS_ROBIN_TFT)
#error "MKS_ROBIN_TFT is now FSMC_GRAPHICAL_TFT. Please update your configuration." #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) #elif defined(SDPOWER)
#error "SDPOWER is now SDPOWER_PIN. Please update your configuration and/or pins." #error "SDPOWER is now SDPOWER_PIN. Please update your configuration and/or pins."
#elif defined(STRING_SPLASH_LINE1) || defined(STRING_SPLASH_LINE2) #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." #error "ANYCUBIC_TFT_MODEL is now ANYCUBIC_LCD_I3MEGA. Please update your Configuration.h."
#elif defined(EVENT_GCODE_SD_STOP) #elif defined(EVENT_GCODE_SD_STOP)
#error "EVENT_GCODE_SD_STOP is now EVENT_GCODE_SD_ABORT. Please update your Configuration.h." #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) #elif defined(FIL_RUNOUT_INVERTING)
#if FIL_RUNOUT_INVERTING #if FIL_RUNOUT_INVERTING
#error "FIL_RUNOUT_INVERTING true is now FIL_RUNOUT_STATE HIGH. Please update your Configuration.h." #error "FIL_RUNOUT_INVERTING true is now FIL_RUNOUT_STATE HIGH. Please update your Configuration.h."
@ -582,7 +582,7 @@
/** /**
* Serial * Serial
*/ */
#if !(defined(__AVR__) && defined(USBCON)) #if !IS_AT90USB
#if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024 #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024
#error "SERIAL_XON_XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops." #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)) #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." #error "TEMP_SENSOR_1 is required with TEMP_SENSOR_1_AS_REDUNDANT."
#endif #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 * 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 #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)." #error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)."
#endif #endif
@ -2667,7 +2671,7 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
/** /**
* Digipot requirement * Digipot requirement
*/ */
#if HAS_I2C_DIGIPOT #if HAS_MOTOR_CURRENT_I2C
#if BOTH(DIGIPOT_MCP4018, DIGIPOT_MCP4451) #if BOTH(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
#error "Enable only one of DIGIPOT_MCP4018 or DIGIPOT_MCP4451." #error "Enable only one of DIGIPOT_MCP4018 or DIGIPOT_MCP4451."
#elif !MB(MKS_SBASE) \ #elif !MB(MKS_SBASE) \
@ -2788,6 +2792,25 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#endif #endif
#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) #if ENABLED(PRINTCOUNTER) && DISABLED(EEPROM_SETTINGS)
#error "PRINTCOUNTER requires EEPROM_SETTINGS. Please update your Configuration." #error "PRINTCOUNTER requires EEPROM_SETTINGS. Please update your Configuration."
#endif #endif

View file

@ -25,7 +25,7 @@
* Release version. Leave the Marlin version or apply a custom scheme. * Release version. Leave the Marlin version or apply a custom scheme.
*/ */
#ifndef SHORT_BUILD_VERSION #ifndef SHORT_BUILD_VERSION
#define SHORT_BUILD_VERSION "2.0.7.1" #define SHORT_BUILD_VERSION "2.0.7.2"
#endif #endif
/** /**
@ -42,7 +42,7 @@
* version was tagged. * version was tagged.
*/ */
#ifndef STRING_DISTRIBUTION_DATE #ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2020-10-10" #define STRING_DISTRIBUTION_DATE "2020-10-15"
#endif #endif
/** /**

View file

@ -1341,7 +1341,7 @@
#undef STATUS_LOGO_WIDTH #undef STATUS_LOGO_WIDTH
#endif #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) #define _STATUS_HEATERS_X(H,S,N) ((LCD_PIXEL_WIDTH - (H * (S + N)) - (_EXTRA_WIDTH) + (STATUS_LOGO_WIDTH)) / 2)
#if STATUS_HOTEND1_WIDTH #if STATUS_HOTEND1_WIDTH
#if HOTENDS > 2 #if HOTENDS > 2

View file

@ -66,12 +66,7 @@
#define HAS_LCD_IO 1 #define HAS_LCD_IO 1
#endif #endif
#if ENABLED(SPI_GRAPHICAL_TFT) #include "../tft_io/tft_io.h"
#include HAL_PATH(../../HAL, tft/tft_spi.h)
#elif ENABLED(FSMC_GRAPHICAL_TFT)
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
#endif
TFT_IO tftio; TFT_IO tftio;
#define WIDTH LCD_PIXEL_WIDTH #define WIDTH LCD_PIXEL_WIDTH
@ -132,299 +127,10 @@ TFT_IO tftio;
#define TFT_BTOKMENU_COLOR COLOR_RED #define TFT_BTOKMENU_COLOR COLOR_RED
#endif #endif
static uint32_t lcd_id = 0; 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);
#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_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 #if HAS_TOUCH_XPT2046
static const uint8_t buttonD[] = { 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) { switch (msg) {
case U8G_DEV_MSG_INIT: case U8G_DEV_MSG_INIT:
dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id); dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, NULL);
tftio.DataTransferBegin(DATASIZE_8BIT); tftio.Init();
switch (lcd_id & 0xFFFF) { tftio.InitTFT();
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();
if (preinit) { if (preinit) {
preinit = false; 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_STOP: break;
case U8G_COM_MSG_INIT: case U8G_COM_MSG_INIT:
u8g_SetPIOutput(u8g, U8G_PI_RESET); u8g_SetPIOutput(u8g, U8G_PI_RESET);
u8g_Delay(50); u8g_Delay(50);
tftio.Init();
if (arg_ptr) {
*((uint32_t *)arg_ptr) = tftio.GetID();
}
isCommand = 0; isCommand = 0;
break; break;

View file

@ -22,7 +22,7 @@
#include "../../../../inc/MarlinConfigPre.h" #include "../../../../inc/MarlinConfigPre.h"
#if ENABLED(TFT_LVGL_UI_SPI) #if HAS_TFT_LVGL_UI
#include "SPI_TFT.h" #include "SPI_TFT.h"
#include "pic_manager.h" #include "pic_manager.h"
@ -32,6 +32,8 @@
#include <SPI.h> #include <SPI.h>
#include "draw_ui.h"
TFT SPI_TFT; TFT SPI_TFT;
// use SPI1 for the spi tft. // use SPI1 for the spi tft.
@ -39,142 +41,48 @@ void TFT::spi_init(uint8_t spiRate) {
tftio.Init(); 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) { void TFT::SetPoint(uint16_t x, uint16_t y, uint16_t point) {
if ((x > 480) || (y > 320)) return; if ((x > 480) || (y > 320)) return;
SetWindows(x, y, 1, 1); setWindow(x, y, 1, 1);
tftio.WriteMultiple(point, (uint16_t)1); tftio.WriteMultiple(point, (uint16_t)1);
} }
void TFT::SetWindows(uint16_t x, uint16_t y, uint16_t with, uint16_t height) { void TFT::setWindow(uint16_t x, uint16_t y, uint16_t with, uint16_t height) {
tftio.DataTransferBegin(DATASIZE_8BIT); tftio.set_window(x, y, (x + with - 1), (y + height - 1));
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::LCD_init() { void TFT::LCD_init() {
TFT_BLK_L; tftio.InitTFT();
TFT_RST_H; #if PIN_EXISTS(TFT_BACKLIGHT)
delay(150); OUT_WRITE(TFT_BACKLIGHT_PIN, LOW);
TFT_RST_L; #endif
delay(150); delay(100);
TFT_RST_H; LCD_clear(0x0000);
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); //
LCD_Draw_Logo(); LCD_Draw_Logo();
TFT_BLK_H; #if PIN_EXISTS(TFT_BACKLIGHT)
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
#if HAS_LOGO_IN_FLASH
delay(2000); delay(2000);
#endif
} }
void TFT::LCD_clear(uint16_t color) { 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)); tftio.WriteMultiple(color, (uint32_t)(TFT_WIDTH) * (TFT_HEIGHT));
} }
extern unsigned char bmp_public_buf[17 * 1024]; extern unsigned char bmp_public_buf[17 * 1024];
void TFT::LCD_Draw_Logo() { void TFT::LCD_Draw_Logo() {
SetWindows(0, 0, TFT_WIDTH, TFT_HEIGHT); #if HAS_LOGO_IN_FLASH
setWindow(0, 0, TFT_WIDTH, TFT_HEIGHT);
for (uint16_t i = 0; i < (TFT_HEIGHT); i ++) { for (uint16_t i = 0; i < (TFT_HEIGHT); i ++) {
Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (TFT_WIDTH) * 2); Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (TFT_WIDTH) * 2);
tftio.WriteSequence((uint16_t *)bmp_public_buf, TFT_WIDTH); tftio.WriteSequence((uint16_t *)bmp_public_buf, TFT_WIDTH);
} }
#endif
} }
#endif // HAS_TFT_LVGL_UI_SPI #endif // HAS_TFT_LVGL_UI

View file

@ -23,29 +23,21 @@
#include "../../inc/MarlinConfigPre.h" #include "../../inc/MarlinConfigPre.h"
#if ENABLED(TFT_LVGL_UI_SPI) #if HAS_TFT_LVGL_UI
#include HAL_PATH(../../HAL, tft/tft_spi.h)
#elif ENABLED(TFT_LVGL_UI_FSMC)
#include HAL_PATH(../../HAL, tft/tft_fsmc.h)
#endif
#define TFT_RST_H OUT_WRITE(TFT_RESET_PIN, HIGH) #include "../../../tft_io/tft_io.h"
#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)
class TFT { class TFT {
public: public:
TFT_IO tftio; TFT_IO tftio;
void spi_init(uint8_t spiRate); 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 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_init();
void LCD_clear(uint16_t color); void LCD_clear(uint16_t color);
void LCD_Draw_Logo(); void LCD_Draw_Logo();
}; };
extern TFT SPI_TFT; extern TFT SPI_TFT;
#endif // HAS_TFT_LVGL_UI

View file

@ -23,9 +23,7 @@
#if HAS_TFT_LVGL_UI #if HAS_TFT_LVGL_UI
#if ENABLED(TFT_LVGL_UI_SPI) #include "SPI_TFT.h"
#include "SPI_TFT.h"
#endif
#include "lv_conf.h" #include "lv_conf.h"
#include "draw_ui.h" #include "draw_ui.h"
@ -77,7 +75,7 @@ void lv_draw_error_message(PGM_P const msg) {
lv_task_handler(); lv_task_handler();
#endif #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); 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("PRINTER HALTED") * 16) / 2, 140, "PRINTER HALTED", 0xFFFF, 0x0000);
disp_string((TFT_WIDTH - strlen("Please Reset") * 16) / 2, 180, "Please Reset", 0xFFFF, 0x0000); disp_string((TFT_WIDTH - strlen("Please Reset") * 16) / 2, 180, "Please Reset", 0xFFFF, 0x0000);

View file

@ -46,7 +46,8 @@
extern lv_group_t * g; extern lv_group_t * g;
static lv_obj_t * scr; 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 *labelPause, * labelStop, * labelOperat;
static lv_obj_t * bar1, *bar1ValueText; static lv_obj_t * bar1, *bar1ValueText;
static lv_obj_t * buttonPause, *buttonOperat, *buttonStop; 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) { 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; disp_state_stack._disp_index = 0;
ZERO(disp_state_stack._disp_state); ZERO(disp_state_stack._disp_state);
disp_state_stack._disp_state[disp_state_stack._disp_index] = PRINTING_UI; 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()); lv_refr_now(lv_refr_get_disp_refreshing());
// Create image buttons // Create image buttons
buttonExt1 = lv_img_create(scr, NULL); lv_obj_t *buttonExt1 = lv_img_create(scr, NULL);
#if HAS_MULTI_EXTRUDER #if HAS_MULTI_EXTRUDER
buttonExt2 = lv_img_create(scr, NULL); lv_obj_t *buttonExt2 = lv_img_create(scr, NULL);
#endif #endif
#if HAS_HEATED_BED #if HAS_HEATED_BED
buttonBedstate = lv_img_create(scr, NULL); lv_obj_t *buttonBedstate = lv_img_create(scr, NULL);
#endif #endif
buttonFanstate = lv_img_create(scr, NULL); lv_obj_t *buttonFanstate = lv_img_create(scr, NULL);
buttonTime = lv_img_create(scr, NULL); lv_obj_t *buttonTime = lv_img_create(scr, NULL);
buttonZpos = lv_img_create(scr, NULL); lv_obj_t *buttonZpos = lv_img_create(scr, NULL);
buttonPause = lv_imgbtn_create(scr, NULL); buttonPause = lv_imgbtn_create(scr, NULL);
buttonStop = lv_imgbtn_create(scr, NULL); buttonStop = lv_imgbtn_create(scr, NULL);
buttonOperat = lv_imgbtn_create(scr, NULL); buttonOperat = lv_imgbtn_create(scr, NULL);

View file

@ -23,9 +23,7 @@
#if HAS_TFT_LVGL_UI #if HAS_TFT_LVGL_UI
#if ENABLED(TFT_LVGL_UI_SPI) #include "SPI_TFT.h"
#include "SPI_TFT.h"
#endif
#include "tft_lvgl_configuration.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); 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) { if (gCfgItems.disp_rotation_180 != rot) {
gCfgItems.disp_rotation_180 = rot; gCfgItems.disp_rotation_180 = rot;
update_spi_flash(); update_spi_flash();
@ -655,12 +653,7 @@ char *creat_title_text() {
} }
card.setIndex((gPicturePreviewStart + To_pre_view) + size * row + 8); card.setIndex((gPicturePreviewStart + To_pre_view) + size * row + 8);
#if ENABLED(TFT_LVGL_UI_SPI) SPI_TFT.setWindow(xpos_pixel, ypos_pixel + row, 200, 1);
SPI_TFT.SetWindows(xpos_pixel, ypos_pixel + row, 200, 1);
#else
LCD_setWindowArea(xpos_pixel, ypos_pixel + row, 200, 1);
LCD_WriteRAM_Prepare();
#endif
j = i = 0; j = i = 0;
@ -673,20 +666,11 @@ char *creat_title_text() {
} }
if (j >= 400) break; if (j >= 400) break;
} }
#if ENABLED(TFT_LVGL_UI_SPI)
for (i = 0; i < 400; i += 2) { for (i = 0; i < 400; i += 2) {
p_index = (uint16_t *)(&bmp_public_buf[i]); p_index = (uint16_t *)(&bmp_public_buf[i]);
if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full; if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full;
} }
SPI_TFT.tftio.WriteSequence((uint16_t*)bmp_public_buf, 200); 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
#if HAS_BAK_VIEW_IN_FLASH #if HAS_BAK_VIEW_IN_FLASH
W25QXX.init(SPI_QUARTER_SPEED); W25QXX.init(SPI_QUARTER_SPEED);
if (row < 20) W25QXX.SPI_FLASH_SectorErase(BAK_VIEW_ADDR_TFT35 + row * 4096); 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); card.setIndex((PREVIEW_LITTLE_PIC_SIZE + To_pre_view) + size * row + 8);
#if ENABLED(TFT_LVGL_UI_SPI) #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 #else
LCD_setWindowArea(xpos_pixel, ypos_pixel + row, 200, 1); LCD_setWindowArea(xpos_pixel, ypos_pixel + row, 200, 1);
LCD_WriteRAM_Prepare(); LCD_WriteRAM_Prepare();
@ -901,34 +885,9 @@ char *creat_title_text() {
default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k
#endif #endif
#if ENABLED(TFT_LVGL_UI_SPI) SPI_TFT.setWindow(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
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); 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
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++; y_off++;
} }
W25QXX.init(SPI_QUARTER_SPEED); W25QXX.init(SPI_QUARTER_SPEED);

View file

@ -23,9 +23,7 @@
#if HAS_TFT_LVGL_UI #if HAS_TFT_LVGL_UI
#if ENABLED(TFT_LVGL_UI_SPI) #include "SPI_TFT.h"
#include "SPI_TFT.h"
#endif
#include "tft_lvgl_configuration.h" #include "tft_lvgl_configuration.h"
#include "draw_ready_print.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) { 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++) { for (uint16_t i = 0; i < 24; i++) {
const uint16_t tmp_char = pgm_read_word(&ASCII_Table_16x24[((c - 0x20) * 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++) { for (uint16_t j = 0; j < 16; j++)
TERN(TFT_LVGL_UI_SPI, SPI_TFT.SetPoint, tft_set_point) SPI_TFT.SetPoint(x + j, y + i, ((tmp_char >> j) & 0x01) ? charColor : bkColor);
(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; //static lv_obj_t * scr_test;
void disp_assets_update() { 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); disp_string(100, 140, "Assets Updating...", 0xFFFF, 0x0000);
} }

View file

@ -266,20 +266,25 @@ void spiFlashErase_PIC() {
W25QXX.init(SPI_QUARTER_SPEED); W25QXX.init(SPI_QUARTER_SPEED);
//erase 0x001000 -64K //erase 0x001000 -64K
for (pic_sectorcnt = 0; pic_sectorcnt < (64 - 4) / 4; pic_sectorcnt++) { for (pic_sectorcnt = 0; pic_sectorcnt < (64 - 4) / 4; pic_sectorcnt++) {
watchdog_refresh();
W25QXX.SPI_FLASH_SectorErase(PICINFOADDR + pic_sectorcnt * 4 * 1024); W25QXX.SPI_FLASH_SectorErase(PICINFOADDR + pic_sectorcnt * 4 * 1024);
} }
//erase 64K -- 6M //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); W25QXX.SPI_FLASH_BlockErase((pic_sectorcnt + 1) * 64 * 1024);
}
} }
#if HAS_SPI_FLASH_FONT #if HAS_SPI_FLASH_FONT
void spiFlashErase_FONT() { void spiFlashErase_FONT() {
volatile uint32_t Font_sectorcnt = 0; volatile uint32_t Font_sectorcnt = 0;
W25QXX.init(SPI_QUARTER_SPEED); 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); W25QXX.SPI_FLASH_BlockErase(FONTINFOADDR + Font_sectorcnt * 64 * 1024);
} }
}
#endif #endif
uint32_t LogoWrite_Addroffset = 0; uint32_t LogoWrite_Addroffset = 0;
@ -410,6 +415,7 @@ uint8_t public_buf[512];
return; return;
} }
watchdog_refresh();
disp_assets_update_progress(fn); disp_assets_update_progress(fn);
W25QXX.init(SPI_QUARTER_SPEED); W25QXX.init(SPI_QUARTER_SPEED);
@ -422,18 +428,21 @@ uint8_t public_buf[512];
totalSizeLoaded += pfileSize; totalSizeLoaded += pfileSize;
if (assetType == ASSET_TYPE_LOGO) { if (assetType == ASSET_TYPE_LOGO) {
do { do {
watchdog_refresh();
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
Pic_Logo_Write((uint8_t *)fn, public_buf, pbr); Pic_Logo_Write((uint8_t *)fn, public_buf, pbr);
} while (pbr >= BMP_WRITE_BUF_LEN); } while (pbr >= BMP_WRITE_BUF_LEN);
} }
else if (assetType == ASSET_TYPE_TITLE_LOGO) { else if (assetType == ASSET_TYPE_TITLE_LOGO) {
do { do {
watchdog_refresh();
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
Pic_TitleLogo_Write((uint8_t *)fn, public_buf, pbr); Pic_TitleLogo_Write((uint8_t *)fn, public_buf, pbr);
} while (pbr >= BMP_WRITE_BUF_LEN); } while (pbr >= BMP_WRITE_BUF_LEN);
} }
else if (assetType == ASSET_TYPE_G_PREVIEW) { else if (assetType == ASSET_TYPE_G_PREVIEW) {
do { do {
watchdog_refresh();
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
default_view_Write(public_buf, pbr); default_view_Write(public_buf, pbr);
} while (pbr >= BMP_WRITE_BUF_LEN); } while (pbr >= BMP_WRITE_BUF_LEN);
@ -443,6 +452,7 @@ uint8_t public_buf[512];
SPIFlash.beginWrite(Pic_Write_Addr); SPIFlash.beginWrite(Pic_Write_Addr);
#if HAS_SPI_FLASH_COMPRESSION #if HAS_SPI_FLASH_COMPRESSION
do { do {
watchdog_refresh();
pbr = file.read(public_buf, SPI_FLASH_PageSize); pbr = file.read(public_buf, SPI_FLASH_PageSize);
TERN_(MARLIN_DEV_MODE, totalSizes += pbr); TERN_(MARLIN_DEV_MODE, totalSizes += pbr);
SPIFlash.writeData(public_buf, SPI_FLASH_PageSize); SPIFlash.writeData(public_buf, SPI_FLASH_PageSize);
@ -463,6 +473,7 @@ uint8_t public_buf[512];
else if (assetType == ASSET_TYPE_FONT) { else if (assetType == ASSET_TYPE_FONT) {
Pic_Write_Addr = UNIGBK_FLASH_ADDR; Pic_Write_Addr = UNIGBK_FLASH_ADDR;
do { do {
watchdog_refresh();
pbr = file.read(public_buf, BMP_WRITE_BUF_LEN); pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr); W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr);
Pic_Write_Addr += pbr; Pic_Write_Addr += pbr;
@ -482,9 +493,11 @@ uint8_t public_buf[512];
disp_assets_update(); disp_assets_update();
disp_assets_update_progress("Erasing pics..."); disp_assets_update_progress("Erasing pics...");
watchdog_refresh();
spiFlashErase_PIC(); spiFlashErase_PIC();
#if HAS_SPI_FLASH_FONT #if HAS_SPI_FLASH_FONT
disp_assets_update_progress("Erasing fonts..."); disp_assets_update_progress("Erasing fonts...");
watchdog_refresh();
spiFlashErase_FONT(); spiFlashErase_FONT();
#endif #endif

View file

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

View file

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

View file

@ -29,9 +29,7 @@
#if HAS_TFT_LVGL_UI #if HAS_TFT_LVGL_UI
#if ENABLED(TFT_LVGL_UI_SPI) #include "SPI_TFT.h"
#include "SPI_TFT.h"
#endif
#include "tft_lvgl_configuration.h" #include "tft_lvgl_configuration.h"
#include "draw_ready_print.h" #include "draw_ready_print.h"
@ -74,24 +72,6 @@ lv_group_t* g;
uint16_t DeviceCode = 0x9488; uint16_t DeviceCode = 0x9488;
extern uint8_t sel_id; 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; extern uint8_t gcode_preview_over, flash_preview_begin, default_preview_flg;
uint8_t bmp_public_buf[17 * 1024]; uint8_t bmp_public_buf[17 * 1024];
@ -125,317 +105,7 @@ void SysTick_Callback() {
} }
} }
#if DISABLED(TFT_LVGL_UI_SPI) extern uint8_t bmp_public_buf[17 * 1024];
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
void tft_lvgl_init() { void tft_lvgl_init() {
@ -448,17 +118,16 @@ void tft_lvgl_init() {
disp_language_init(); disp_language_init();
//init tft first! //init tft first!
#if ENABLED(TFT_LVGL_UI_SPI)
SPI_TFT.spi_init(SPI_FULL_SPEED); SPI_TFT.spi_init(SPI_FULL_SPEED);
SPI_TFT.LCD_init(); SPI_TFT.LCD_init();
#else
fsmc_tft_init();
#endif
//spi_flash_read_test(); //spi_flash_read_test();
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
watchdog_refresh();
UpdateAssets(); UpdateAssets();
#endif #endif
watchdog_refresh();
mks_test_get(); mks_test_get();
touch.Init(); 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) { 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; width = area->x2 - area->x1 + 1;
height = area->y2 - area->y1 + 1; height = area->y2 - area->y1 + 1;
SPI_TFT.SetWindows((uint16_t)area->x1, (uint16_t)area->y1, width, height); SPI_TFT.setWindow((uint16_t)area->x1, (uint16_t)area->y1, width, height);
for (i = 0; i < height; i++) { for (i = 0; i < height; i++) {
SPI_TFT.tftio.WriteSequence((uint16_t*)(color_p + width * i), width); SPI_TFT.tftio.WriteSequence((uint16_t*)(color_p + width * i), width);
} }
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/ lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
W25QXX.init(SPI_QUARTER_SPEED); 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
} }
#define TICK_CYCLE 1 #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; *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)); *x = int16_t((TFT_WIDTH) - (int)(*x));
*y = int16_t((TFT_HEIGHT) - (int)(*y)); *y = int16_t((TFT_HEIGHT) - (int)(*y));
#endif #endif
@ -799,13 +445,14 @@ void lv_encoder_pin_init() {
//static const int8_t encoderDirection = 1; //static const int8_t encoderDirection = 1;
//static int16_t enc_Direction; //static int16_t enc_Direction;
void lv_update_encoder() { void lv_update_encoder() {
static uint8_t buttons;
static uint32_t encoder_time1; static uint32_t encoder_time1;
uint32_t tmpTime, diffTime = 0; uint32_t tmpTime, diffTime = 0;
tmpTime = millis(); tmpTime = millis();
diffTime = getTickDiff(tmpTime, encoder_time1); diffTime = getTickDiff(tmpTime, encoder_time1);
if (diffTime > 50) { if (diffTime > 50) {
#if HAS_ENCODER_WHEEL
#if ANY_BUTTON(EN1, EN2, ENC, BACK) #if ANY_BUTTON(EN1, EN2, ENC, BACK)
uint8_t newbutton = 0; uint8_t newbutton = 0;
@ -829,9 +476,8 @@ void lv_encoder_pin_init() {
#endif #endif
static uint8_t buttons = 0;
buttons = newbutton; buttons = newbutton;
#if HAS_ENCODER_WHEEL
static uint8_t lastEncoderBits; static uint8_t lastEncoderBits;
#define encrot0 0 #define encrot0 0

View file

@ -32,7 +32,7 @@
#include <lvgl.h> #include <lvgl.h>
//#define GRAPHICAL_TFT_ROTATE_180 //#define TFT_ROTATION TFT_ROTATE_180
#define USE_WIFI_FUNCTION 0 #define USE_WIFI_FUNCTION 0
extern void tft_lvgl_init(); extern void tft_lvgl_init();

View file

@ -110,23 +110,16 @@ const char *resultMessages[] = {
// 230400b always manages to connect. // 230400b always manages to connect.
static const uint32_t uploadBaudRates[] = { 460800, 230400, 115200, 74880 }; static const uint32_t uploadBaudRates[] = { 460800, 230400, 115200, 74880 };
signed char IsReady() { signed char IsReady() {
return esp_upload.state == upload_idle; return esp_upload.state == upload_idle;
} }
void uploadPort_write(const uint8_t *buf, size_t len) { void uploadPort_write(const uint8_t *buf, size_t len) {
#if 0 #if 0
int i; int i;
for(i = 0; i < len; i++) { for (i = 0; i < len; i++) {
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { /* nada */ }
USART_SendData(USART1, *(buf + i)); USART_SendData(USART1, *(buf + i));
} }
#endif #endif
@ -138,28 +131,22 @@ char uploadPort_read() {
return retChar; return retChar;
else else
return 0; return 0;
} }
int uploadPort_available() { int uploadPort_available() {
return usartFifoAvailable(&WifiRxFifo); return usartFifoAvailable(&WifiRxFifo);
} }
void uploadPort_begin() { void uploadPort_begin() {
esp_port_begin(1); esp_port_begin(1);
} }
void uploadPort_close() { void uploadPort_close() {
//WIFI_COM.end(); //WIFI_COM.end();
//WIFI_COM.begin(115200, true); //WIFI_COM.begin(115200, true);
esp_port_begin(0); esp_port_begin(0);
} }
void flushInput() { void flushInput() {
while (uploadPort_available() != 0) { while (uploadPort_available() != 0) {
(void)uploadPort_read(); (void)uploadPort_read();
@ -304,7 +291,6 @@ EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t
*bodyLen = 0; *bodyLen = 0;
while (state != done) { while (state != done) {
uint8_t c; uint8_t c;
EspUploadResult stat; EspUploadResult stat;
@ -322,7 +308,7 @@ EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t
} }
// sufficient bytes have been received for the current state, process them // sufficient bytes have been received for the current state, process them
switch(state) { switch (state) {
case begin: // expecting frame start case begin: // expecting frame start
c = uploadPort_read(); c = uploadPort_read();
if (c != (uint8_t)0xC0) { if (c != (uint8_t)0xC0) {
@ -397,7 +383,7 @@ EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t
opRet = (uint8_t)getData(1, hdr, 1); opRet = (uint8_t)getData(1, hdr, 1);
// Sync packets often provoke a response with a zero opcode instead of ESP_SYNC // Sync packets often provoke a response with a zero opcode instead of ESP_SYNC
if (resp != 0x01 || opRet != op) { if (resp != 0x01 || opRet != op) {
//debug//printf("resp %02x %02x\n", resp, opRet); //printf("resp %02x %02x\n", resp, opRet); //debug
return respHeader; return respHeader;
} }
@ -432,7 +418,6 @@ void _writePacket(const uint8_t *data, size_t len) {
// 0xC0 and 0xDB replaced by the two-byte sequences {0xDB, 0xDC} and {0xDB, 0xDD} respectively. // 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) { 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(hdr, hdrLen); // send the header
_writePacket(data, dataLen); // send the data block _writePacket(data, dataLen); // send the data block
@ -460,12 +445,10 @@ void sendCommand(uint8_t op, uint32_t checkVal, const uint8_t *data, size_t data
// send the packet // send the packet
//flushInput(); //flushInput();
if (op == ESP_SYNC) { if (op == ESP_SYNC)
writePacketRaw(hdr, sizeof(hdr), data, dataLen); writePacketRaw(hdr, sizeof(hdr), data, dataLen);
} else
else {
writePacket(hdr, sizeof(hdr), data, dataLen); writePacket(hdr, sizeof(hdr), data, dataLen);
}
} }
// Send a command to the attached device together with the supplied data, if any, and get the response // 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); sendCommand(op, checkVal, data, dataLen);
stat = readPacket(op, valp, &bodyLen, msTimeout); stat = readPacket(op, valp, &bodyLen, msTimeout);
if (stat == success && bodyLen != 2) { if (stat == success && bodyLen != 2)
stat = badReply; stat = badReply;
}
return stat; 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); //printf("Upload %d\%\n", ftell(&esp_upload.uploadFile) * 100 / esp_upload.fileSize);
return stat; return stat;
#else
return success;
#endif #endif
} }
@ -625,15 +609,14 @@ void upload_spin() {
esp_upload.uploadResult = connected; esp_upload.uploadResult = connected;
esp_upload.state = done; esp_upload.state = done;
} }
else{ else {
// Reset the serial port at the new baud rate. Also reset the ESP8266. // 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) { if (esp_upload.connectAttemptNumber % esp_upload.retriesPerBaudRate == 0) {
} }
// uploadPort.begin(baud); //uploadPort.begin(baud);
// uploadPort_close(); //uploadPort_close();
uploadPort_begin(); uploadPort_begin();
@ -654,7 +637,7 @@ void upload_spin() {
esp_upload.lastAttemptTime = getWifiTick(); esp_upload.lastAttemptTime = getWifiTick();
if (res == success) { if (res == success) {
// Successful connection // Successful connection
// //MessageF(" success on attempt %d\n", (connectAttemptNumber % retriesPerBaudRate) + 1); //MessageF(" success on attempt %d\n", (connectAttemptNumber % retriesPerBaudRate) + 1);
//printf("connect success\n"); //printf("connect success\n");
esp_upload.state = erasing; esp_upload.state = erasing;
} }
@ -675,11 +658,10 @@ void upload_spin() {
const uint32_t sectorSize = 4096; const uint32_t sectorSize = 4096;
const uint32_t numSectors = (esp_upload.fileSize + sectorSize - 1)/sectorSize; const uint32_t numSectors = (esp_upload.fileSize + sectorSize - 1)/sectorSize;
const uint32_t startSector = esp_upload.uploadAddress/sectorSize; const uint32_t startSector = esp_upload.uploadAddress/sectorSize;
uint32_t headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
if (numSectors < headSectors) { uint32_t headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
headSectors = numSectors; NOMORE(headSectors, numSectors);
}
eraseSize = (numSectors < 2 * headSectors) eraseSize = (numSectors < 2 * headSectors)
? (numSectors + 1) / 2 * sectorSize ? (numSectors + 1) / 2 * sectorSize
: (numSectors - headSectors) * sectorSize; : (numSectors - headSectors) * sectorSize;

View file

@ -305,27 +305,9 @@ namespace ExtUI {
} }
void setAxisPosition_mm(const float position, const axis_t axis, const feedRate_t feedrate/*=0*/) { void setAxisPosition_mm(const float position, const axis_t axis, const feedRate_t feedrate/*=0*/) {
// Start with no limits to movement // Get motion limit from software endstops, if any
float min = current_position[axis] - 1000, float min, max;
max = current_position[axis] + 1000; soft_endstop.get_manual_axis_limits((AxisEnum)axis, min, max);
// 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
// Delta limits XY based on the current offset from center // Delta limits XY based on the current offset from center
// This assumes the center is 0,0 // This assumes the center is 0,0
@ -389,8 +371,8 @@ namespace ExtUI {
} }
#if HAS_SOFTWARE_ENDSTOPS #if HAS_SOFTWARE_ENDSTOPS
bool getSoftEndstopState() { return soft_endstops_enabled; } bool getSoftEndstopState() { return soft_endstop._enabled; }
void setSoftEndstopState(const bool value) { soft_endstops_enabled = value; } void setSoftEndstopState(const bool value) { soft_endstop._enabled = value; }
#endif #endif
#if HAS_TRINAMIC_CONFIG #if HAS_TRINAMIC_CONFIG

View file

@ -67,6 +67,9 @@ namespace Language_en {
PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home Z"); 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_AUTO_Z_ALIGN = _UxGT("Auto Z-Align");
PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Assisted Tramming"); 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_HOMING = _UxGT("Homing XYZ");
PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Click to Begin"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Click to Begin");
PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Next Point"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Next Point");

View file

@ -58,16 +58,16 @@
void menu_tmc(); void menu_tmc();
void menu_backlash(); void menu_backlash();
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
#include "../../feature/dac/stepper_dac.h" #include "../../feature/dac/stepper_dac.h"
void menu_dac() { void menu_dac() {
static xyze_uint8_t driverPercent; 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(); START_MENU();
BACK_ITEM(MSG_ADVANCED_SETTINGS); 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(X);
EDIT_DAC_PERCENT(Y); EDIT_DAC_PERCENT(Y);
EDIT_DAC_PERCENT(Z); EDIT_DAC_PERCENT(Z);
@ -568,7 +568,7 @@ void menu_advanced_settings() {
SUBMENU(MSG_BACKLASH, menu_backlash); SUBMENU(MSG_BACKLASH, menu_backlash);
#endif #endif
#if ENABLED(DAC_STEPPER_CURRENT) #if ENABLED(HAS_MOTOR_CURRENT_DAC)
SUBMENU(MSG_DRIVE_STRENGTH, menu_dac); SUBMENU(MSG_DRIVE_STRENGTH, menu_dac);
#endif #endif
#if HAS_MOTOR_CURRENT_PWM #if HAS_MOTOR_CURRENT_PWM

View file

@ -118,7 +118,7 @@ void lcd_delta_settings() {
} }
void menu_delta_calibrate() { 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(); START_MENU();
BACK_ITEM(MSG_MAIN); BACK_ITEM(MSG_MAIN);

View file

@ -57,28 +57,9 @@
static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) { 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.use_click()) return ui.goto_previous_screen_no_defer();
if (ui.encoderPosition && !ui.manual_move.processing) { if (ui.encoderPosition && !ui.manual_move.processing) {
// Get motion limit from software endstops, if any
// Start with no limits to movement float min, max;
float min = current_position[axis] - 1000, soft_endstop.get_manual_axis_limits(axis, min, max);
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
// Delta limits XY based on the current offset from center // Delta limits XY based on the current offset from center
// This assumes the center is 0,0 // This assumes the center is 0,0
@ -238,7 +219,7 @@ void menu_move() {
BACK_ITEM(MSG_MOTION); BACK_ITEM(MSG_MOTION);
#if BOTH(HAS_SOFTWARE_ENDSTOPS, SOFT_ENDSTOPS_MENU_ITEM) #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 #endif
if (NONE(IS_KINEMATIC, NO_MOTION_BEFORE_HOMING) || all_axes_homed()) { if (NONE(IS_KINEMATIC, NO_MOTION_BEFORE_HOMING) || all_axes_homed()) {
@ -358,7 +339,7 @@ void menu_motion() {
// //
// Auto Z-Align // 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")); GCODES_ITEM(MSG_AUTO_Z_ALIGN, PSTR("G34"));
#endif #endif

View file

@ -48,16 +48,12 @@
float z_offset_backup, calculated_z_offset; float z_offset_backup, calculated_z_offset;
TERN_(HAS_LEVELING, bool leveling_was_active); TERN_(HAS_LEVELING, bool leveling_was_active);
TERN_(HAS_SOFTWARE_ENDSTOPS, bool store_soft_endstops_enabled);
void prepare_for_calibration() { void prepare_for_calibration() {
z_offset_backup = probe.offset.z; z_offset_backup = probe.offset.z;
// Disable soft endstops for free Z movement // Disable soft endstops for free Z movement
#if HAS_SOFTWARE_ENDSTOPS SET_SOFT_ENDSTOP_LOOSE(true);
store_soft_endstops_enabled = soft_endstops_enabled;
soft_endstops_enabled = false;
#endif
// Disable leveling for raw planner motion // Disable leveling for raw planner motion
#if HAS_LEVELING #if HAS_LEVELING
@ -68,7 +64,7 @@ void prepare_for_calibration() {
void set_offset_and_go_back(const float &z) { void set_offset_and_go_back(const float &z) {
probe.offset.z = 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)); TERN_(HAS_LEVELING, set_bed_leveling_enabled(leveling_was_active));
ui.goto_previous_screen_no_defer(); ui.goto_previous_screen_no_defer();
} }

View file

@ -188,11 +188,10 @@ void _lcd_ubl_edit_mesh() {
*/ */
void _lcd_ubl_validate_custom_mesh() { void _lcd_ubl_validate_custom_mesh() {
char ubl_lcd_gcode[24]; 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)) sprintf_P(ubl_lcd_gcode, PSTR("G28\nG26 C P H%" PRIi16 TERN_(HAS_HEATED_BED, " B%" PRIi16))
, custom_hotend_temp , custom_hotend_temp
#if HAS_HEATED_BED #if HAS_HEATED_BED
, temp , custom_bed_temp
#endif #endif
); );
queue.inject(ubl_lcd_gcode); queue.inject(ubl_lcd_gcode);

View file

@ -43,8 +43,13 @@
#endif #endif
#ifndef TFT_PIXEL_OFFSET_X #ifndef TFT_PIXEL_OFFSET_X
#if GRAPHICAL_TFT_UPSCALE == 2
#define TFT_PIXEL_OFFSET_X 32
#else
#define TFT_PIXEL_OFFSET_X 48 #define TFT_PIXEL_OFFSET_X 48
#endif
#endif #endif
#ifndef TFT_PIXEL_OFFSET_Y #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 #endif

View file

@ -25,173 +25,16 @@
#if HAS_GRAPHICAL_TFT #if HAS_GRAPHICAL_TFT
#include "tft.h" #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_GRAPHICAL_TFT
#define DEBUG_OUT ENABLED(DEBUG_GRAPHICAL_TFT) #define DEBUG_OUT ENABLED(DEBUG_GRAPHICAL_TFT)
#include "../../core/debug_out.h" #include "../../core/debug_out.h"
uint16_t TFT::buffer[]; uint16_t TFT::buffer[];
uint32_t TFT::lcd_id = 0xFFFFFFFF;
void TFT::init() { void TFT::init() {
if (lcd_id != 0xFFFFFFFF) return;
io.Init(); io.Init();
io.InitTFT();
#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();
} }
TFT tft; TFT tft;

View file

@ -26,7 +26,7 @@
#include "tft_color.h" #include "tft_color.h"
#include "tft_string.h" #include "tft_string.h"
#include "tft_image.h" #include "tft_image.h"
#include "tft_io.h" #include "../tft_io/tft_io.h"
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
@ -40,20 +40,6 @@
#error "Unsupported display resolution!" #error "Unsupported display resolution!"
#endif #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 #ifndef TFT_BUFFER_SIZE
#ifdef STM32F103xB #ifdef STM32F103xB
#define TFT_BUFFER_SIZE 1024 #define TFT_BUFFER_SIZE 1024
@ -71,14 +57,8 @@
#error "TFT_BUFFER_SIZE can not exceed 65535" #error "TFT_BUFFER_SIZE can not exceed 65535"
#endif #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 { class TFT {
private: private:
static uint32_t lcd_id;
static TFT_String string; static TFT_String string;
static TFT_IO io; 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 set_font(const uint8_t *Font) { string.set_font(Font); }
static inline void add_glyphs(const uint8_t *Font) { string.add_glyphs(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 bool is_busy() { return io.isBusy(); }
static inline void abort() { io.Abort(); } 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_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 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 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); } static inline void canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { queue.canvas(x, y, width, height); }

View file

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

View file

@ -116,6 +116,17 @@ void TFT_String::add(uint8_t *string, int8_t index, uint8_t *itemString) {
eol(); 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) { void TFT_String::add_character(uint8_t character) {
if (length < MAX_STRING_LENGTH) { if (length < MAX_STRING_LENGTH) {
data[length] = character; data[length] = character;

View file

@ -85,7 +85,7 @@ class TFT_String {
static void set(); static void set();
static void add(uint8_t character) { add_character(character); eol(); } 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 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) { set(); add(string); };
static void set(uint8_t *string, int8_t index, const char *itemString = NULL) { set(); add(string, index, (uint8_t *)itemString); }; static void set(uint8_t *string, int8_t index, const char *itemString = NULL) { set(); add(string, index, (uint8_t *)itemString); };

View file

@ -50,6 +50,9 @@ touch_calibration_t Touch::calibration;
calibrationState Touch::calibration_state = CALIBRATION_NONE; calibrationState Touch::calibration_state = CALIBRATION_NONE;
touch_calibration_point_t Touch::calibration_points[4]; touch_calibration_point_t Touch::calibration_points[4];
#endif #endif
#if HAS_RESUME_CONTINUE
extern bool wait_for_user;
#endif
void Touch::init() { void Touch::init() {
calibration_reset(); calibration_reset();
@ -80,6 +83,15 @@ void Touch::idle() {
now = millis(); now = millis();
if (get_point(&_x, &_y)) { 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 #if LCD_TIMEOUT_TO_STATUS
ui.return_to_status_ms = now + LCD_TIMEOUT_TO_STATUS; ui.return_to_status_ms = now + LCD_TIMEOUT_TO_STATUS;
#endif #endif

View file

@ -813,27 +813,9 @@ static void moveAxis(AxisEnum axis, const int8_t direction) {
} }
if (!ui.manual_move.processing) { if (!ui.manual_move.processing) {
// Start with no limits to movement // Get motion limit from software endstops, if any
float min = current_position[axis] - 1000, float min, max;
max = current_position[axis] + 1000; soft_endstop.get_manual_axis_limits(axis, min, max);
// 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
// Delta limits XY based on the current offset from center // Delta limits XY based on the current offset from center
// This assumes the center is 0,0 // This assumes the center is 0,0

View file

@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#include "tft.h" #include "tft_io.h"
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
@ -40,8 +40,31 @@
#define ILI9328_ETMOD_AM 0x0008 // 0 - Horizontal / 1 - Vertical #define ILI9328_ETMOD_AM 0x0008 // 0 - Horizontal / 1 - Vertical
// MKS Robin TFT v1.1 - 320x240 ; Cable on the left side // 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_RDDID 0x00 // ID code - 0x9328
#define ILI9328_DRVCTL 0x01 // Driver Output Control #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_PWCTRL7), 0x0004,
ESC_REG(ILI9328_FRMCTR), 0x000D, ESC_REG(ILI9328_FRMCTR), 0x000D,
ESC_DELAY(50), 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_SCANCTL2), 0x0001,
ESC_REG(ILI9328_GATE_SCANCTL3), 0x0000, ESC_REG(ILI9328_GATE_SCANCTL3), 0x0000,
ESC_REG(ILI9328_PLTPOS1), 0x0000, ESC_REG(ILI9328_PLTPOS1), 0x0000,

View file

@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#include "tft.h" #include "tft_io.h"
#include "../../inc/MarlinConfig.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_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 #define ILI9341_ORIENTATION_DOWN ILI9341_MADCTL_MX // 240x320 ; Cable on the upper side
#ifndef ILI9341_COLOR_RGB #define ILI9341_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9341_MADCTL_MV) | \
#define ILI9341_COLOR_BGR 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 #endif
#ifndef ILI9341_ORIENTATION
#define ILI9341_ORIENTATION ILI9341_ORIENTATION_LEFT #define ILI9341_MADCTL_DATA (ILI9341_ORIENTATION) | (ILI9341_COLOR)
#endif
#define ILI9341_MADCTL_DATA (ILI9341_ORIENTATION | TERN(ILI9341_COLOR_BGR, ILI9341_MADCTL_BGR, ILI9341_MADCTL_RGB))
#define ILI9341_NOP 0x00 // No Operation #define ILI9341_NOP 0x00 // No Operation
#define ILI9341_SWRESET 0x01 // Software Reset #define ILI9341_SWRESET 0x01 // Software Reset

View file

@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#include "tft.h" #include "tft_io.h"
#include "../../inc/MarlinConfig.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_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 #define ILI9488_ORIENTATION_DOWN ILI9488_MADCTL_MX // 320x480 ; Cable on the upper side
#ifndef ILI9488_COLOR_RGB #define ILI9488_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ILI9488_MADCTL_MV) | \
#define ILI9488_COLOR_BGR 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 #endif
#ifndef ILI9488_ORIENTATION
#define ILI9488_ORIENTATION ILI9488_ORIENTATION_LEFT #define ILI9488_MADCTL_DATA (ILI9488_ORIENTATION) | (ILI9488_COLOR)
#endif
#define ILI9488_MADCTL_DATA (ILI9488_ORIENTATION | TERN(ILI9488_COLOR_BGR, ILI9488_MADCTL_BGR, ILI9488_MADCTL_RGB))
#define ILI9488_NOP 0x00 // No Operation #define ILI9488_NOP 0x00 // No Operation
#define ILI9488_SWRESET 0x01 // Software Reset #define ILI9488_SWRESET 0x01 // Software Reset

View file

@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#include "tft.h" #include "tft_io.h"
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
@ -42,9 +42,30 @@
#define R61505_DRVCTRL_GS 0x8000 // Gate Scan direction #define R61505_DRVCTRL_GS 0x8000 // Gate Scan direction
// MKS Robin TFT v1.1 - 320x240 ; Cable on the left side // 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 #if TFT_ROTATION == TFT_ROTATE_180
#define R61505_DRVCTRL_GSDIR R61505_DRVCTRL_GS #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 #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_GAMCTRL9), 0x0700,
ESC_REG(R61505_GAMCTRLA), 0x0A1F, 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_BASE_IMAGE_CTRL), 0x0001,
ESC_REG(R61505_VSCROLL_CTRL), 0x0000, ESC_REG(R61505_VSCROLL_CTRL), 0x0000,

View 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
};

View file

@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#include "tft.h" #include "tft_io.h"
#include "../../inc/MarlinConfig.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_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_ORIENTATION_DOWN ST7735_MADCTL_MX | ST7735_MADCTL_MY // 128x160 ; Cable on the lower side
//#define ST7735_COLOR_BGR #define ST7735_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7735_MADCTL_MV) | \
#define ST7735_ORIENTATION ST7735_ORIENTATION_DOWN IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7735_MADCTL_MX) | \
#define ST7735_MADCTL_DATA (ST7735_ORIENTATION | TERN(ST7735_COLOR_BGR, ST7735_MADCTL_BGR, ST7735_MADCTL_RGB)) 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_NOP 0x00 // No Operation
#define ST7735_SWRESET 0x01 // Software reset #define ST7735_SWRESET 0x01 // Software reset

View file

@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#include "tft.h" #include "tft_io.h"
#include "../../inc/MarlinConfig.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_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_ORIENTATION_DOWN 0 // 240x320 ; Cable on the lower side
//#define ST7789V_COLOR_BGR #define ST7789V_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7789V_MADCTL_MV) | \
#ifndef ST7789V_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7789V_MADCTL_MX) | \
#define ST7789V_ORIENTATION ST7789V_ORIENTATION_LEFT 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 #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_NOP 0x00 // No Operation
#define ST7789V_SWRESET 0x01 // Software reset #define ST7789V_SWRESET 0x01 // Software reset

View file

@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#include "tft.h" #include "tft_io.h"
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
@ -33,9 +33,17 @@
#define ST7796S_MADCTL_RGB 0x00 #define ST7796S_MADCTL_RGB 0x00
#define ST7796S_MADCTL_MH 0x04 // Horizontal Refresh Order #define ST7796S_MADCTL_MH 0x04 // Horizontal Refresh Order
#define ST7796S_COLOR_BGR #define ST7796S_ORIENTATION IF_0((TFT_ORIENTATION) & TFT_EXCHANGE_XY, ST7796S_MADCTL_MV) | \
#define ST7796S_ORIENTATION ST7796S_MADCTL_MV IF_0((TFT_ORIENTATION) & TFT_INVERT_X, ST7796S_MADCTL_MX) | \
#define ST7796S_MADCTL_DATA (ST7796S_ORIENTATION | TERN(ST7796S_COLOR_BGR, ST7796S_MADCTL_BGR, ST7796S_MADCTL_RGB)) 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_NOP 0x00 // No Operation
#define ST7796S_SWRESET 0x01 // Software reset #define ST7796S_SWRESET 0x01 // Software reset

View 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

View 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