Browse Source

Обновление 2.0.6.1

pull/6/head
Sergey 4 years ago
parent
commit
adee4a7475
  1. 233
      Marlin/Configuration.h
  2. 83
      Marlin/Configuration_adv.h
  3. 2
      Marlin/Version.h
  4. 11
      Marlin/src/HAL/AVR/HAL.h
  5. 18
      Marlin/src/HAL/AVR/MarlinSerial.cpp
  6. 17
      Marlin/src/HAL/AVR/MarlinSerial.h
  7. 8
      Marlin/src/HAL/AVR/ServoTimers.h
  8. 4
      Marlin/src/HAL/AVR/inc/Conditionals_LCD.h
  9. 3
      Marlin/src/HAL/AVR/inc/SanityCheck.h
  10. 1
      Marlin/src/HAL/DUE/HAL.cpp
  11. 4
      Marlin/src/HAL/DUE/inc/Conditionals_LCD.h
  12. 2
      Marlin/src/HAL/DUE/usb/arduino_due_x.h
  13. 4
      Marlin/src/HAL/ESP32/inc/Conditionals_LCD.h
  14. 1
      Marlin/src/HAL/ESP32/ota.cpp
  15. 2
      Marlin/src/HAL/HAL.h
  16. 4
      Marlin/src/HAL/LINUX/inc/Conditionals_LCD.h
  17. 252
      Marlin/src/HAL/LPC1768/HAL_SPI.cpp
  18. 11
      Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h
  19. 140
      Marlin/src/HAL/LPC1768/include/SPI.h
  20. 153
      Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
  21. 77
      Marlin/src/HAL/LPC1768/tft/tft_spi.h
  22. 129
      Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
  23. 80
      Marlin/src/HAL/LPC1768/tft/xpt2046.h
  24. 0
      Marlin/src/HAL/LPC1768/upload_extra_script.py
  25. 27
      Marlin/src/HAL/SAMD51/endstop_interrupts.h
  26. 4
      Marlin/src/HAL/SAMD51/inc/Conditionals_LCD.h
  27. 5
      Marlin/src/HAL/STM32/HAL.h
  28. 73
      Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
  29. 10
      Marlin/src/HAL/STM32/SoftwareSerial.cpp
  30. 180
      Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
  31. 160
      Marlin/src/HAL/STM32/tft/tft_fsmc.h
  32. 212
      Marlin/src/HAL/STM32/tft/tft_spi.cpp
  33. 67
      Marlin/src/HAL/STM32/tft/tft_spi.h
  34. 185
      Marlin/src/HAL/STM32/tft/xpt2046.cpp
  35. 86
      Marlin/src/HAL/STM32/tft/xpt2046.h
  36. 19
      Marlin/src/HAL/STM32F1/HAL.h
  37. 2
      Marlin/src/HAL/STM32F1/SPI.cpp
  38. 2
      Marlin/src/HAL/STM32F1/SPI.h
  39. 198
      Marlin/src/HAL/STM32F1/eeprom_i2c_at24.cpp
  40. 2
      Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp
  41. 23
      Marlin/src/HAL/STM32F1/eeprom_spi_w25q.cpp
  42. 16
      Marlin/src/HAL/STM32F1/eeprom_wired.cpp
  43. 7
      Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h
  44. 4
      Marlin/src/HAL/STM32F1/inc/SanityCheck.h
  45. 6
      Marlin/src/HAL/STM32F1/onboard_sd.cpp
  46. 5
      Marlin/src/HAL/STM32F1/onboard_sd.h
  47. 51
      Marlin/src/HAL/STM32F1/small_spi.cpp
  48. 34
      Marlin/src/HAL/STM32F1/small_spi.h
  49. 211
      Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp
  50. 71
      Marlin/src/HAL/STM32F1/tft/tft_fsmc.h
  51. 149
      Marlin/src/HAL/STM32F1/tft/tft_spi.cpp
  52. 72
      Marlin/src/HAL/STM32F1/tft/tft_spi.h
  53. 141
      Marlin/src/HAL/STM32F1/tft/xpt2046.cpp
  54. 80
      Marlin/src/HAL/STM32F1/tft/xpt2046.h
  55. 167
      Marlin/src/HAL/STM32F1/w25q64.cpp
  56. 44
      Marlin/src/HAL/STM32F1/w25q64.h
  57. 2
      Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp
  58. 4
      Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h
  59. 4
      Marlin/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h
  60. 4
      Marlin/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h
  61. 2
      Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp
  62. 4
      Marlin/src/HAL/shared/eeprom_if.h
  63. 3
      Marlin/src/HAL/shared/eeprom_if_i2c.cpp
  64. 7
      Marlin/src/HAL/shared/eeprom_if_spi.cpp
  65. 78
      Marlin/src/MarlinCore.cpp
  66. 4
      Marlin/src/MarlinCore.h
  67. 14
      Marlin/src/core/boards.h
  68. 11
      Marlin/src/core/language.h
  69. 51
      Marlin/src/core/macros.h
  70. 0
      Marlin/src/core/multi_language.cpp
  71. 5
      Marlin/src/feature/babystep.cpp
  72. 2
      Marlin/src/feature/bedlevel/ubl/ubl.cpp
  73. 6
      Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
  74. 4
      Marlin/src/feature/binary_stream.cpp
  75. 0
      Marlin/src/feature/binary_stream.h
  76. 48
      Marlin/src/feature/caselight.cpp
  77. 26
      Marlin/src/feature/caselight.h
  78. 2
      Marlin/src/feature/dac/dac_mcp4728.cpp
  79. 49
      Marlin/src/feature/direct_stepping.cpp
  80. 6
      Marlin/src/feature/direct_stepping.h
  81. 2
      Marlin/src/feature/e_parser.cpp
  82. 2
      Marlin/src/feature/e_parser.h
  83. 60
      Marlin/src/feature/leds/leds.cpp
  84. 53
      Marlin/src/feature/leds/leds.h
  85. 67
      Marlin/src/feature/leds/neopixel.cpp
  86. 79
      Marlin/src/feature/leds/neopixel.h
  87. 2
      Marlin/src/feature/leds/pca9533.cpp
  88. 2
      Marlin/src/feature/leds/pca9533.h
  89. 4
      Marlin/src/feature/leds/pca9632.cpp
  90. 4
      Marlin/src/feature/leds/pca9632.h
  91. 2
      Marlin/src/feature/leds/printer_event_leds.cpp
  92. 2
      Marlin/src/feature/leds/printer_event_leds.h
  93. 58
      Marlin/src/feature/password/password.cpp
  94. 57
      Marlin/src/feature/password/password.h
  95. 7
      Marlin/src/feature/pause.cpp
  96. 5
      Marlin/src/feature/power.cpp
  97. 4
      Marlin/src/feature/powerloss.cpp
  98. 2
      Marlin/src/feature/powerloss.h
  99. 8
      Marlin/src/feature/runout.cpp
  100. 37
      Marlin/src/feature/runout.h

233
Marlin/Configuration.h

@ -178,7 +178,7 @@
#endif
/**
* Prusa Multi-Material Unit v2
* Průša Multi-Material Unit v2
*
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
* Requires EXTRUDERS = 5
@ -236,8 +236,8 @@
#elif ENABLED(MAGNETIC_PARKING_EXTRUDER)
#define MPE_FAST_SPEED 9000 // (mm/m) Speed for travel before last distance point
#define MPE_SLOW_SPEED 4500 // (mm/m) Speed for last distance travel to park and couple
#define MPE_FAST_SPEED 9000 // (mm/min) Speed for travel before last distance point
#define MPE_SLOW_SPEED 4500 // (mm/min) Speed for last distance travel to park and couple
#define MPE_TRAVEL_DISTANCE 10 // (mm) Last distance point
#define MPE_COMPENSATION 0 // Offset Compensation -1 , 0 , 1 (multiplier) only for coupling
@ -285,8 +285,8 @@
#if ENABLED(PRIME_BEFORE_REMOVE)
#define SWITCHING_TOOLHEAD_PRIME_MM 20 // (mm) Extruder prime length
#define SWITCHING_TOOLHEAD_RETRACT_MM 10 // (mm) Retract after priming length
#define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/m) Extruder prime feedrate
#define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/m) Extruder retract feedrate
#define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/min) Extruder prime feedrate
#define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/min) Extruder retract feedrate
#endif
#elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
#define SWITCHING_TOOLHEAD_Z_HOP 2 // (mm) Z raise for switching
@ -331,7 +331,7 @@
//#define PSU_NAME "Power Supply"
#if ENABLED(PSU_CONTROL)
#define PSU_ACTIVE_HIGH false // Set 'false' for ATX, 'true' for X-Box
#define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
@ -374,7 +374,7 @@
* 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
* 5 : 100K thermistor - ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan, J-Head, and E3D) (4.7k pullup)
* 501 : 100K Zonestar (Tronxy X3A) Thermistor
* 502 : 100K Zonestar Thermistor used by hot bed in Zonestar Prusa P802M
* 502 : 100K Zonestar Thermistor used by hot bed in Zonestar Průša P802M
* 512 : 100k RPW-Ultra hotend thermistor (4.7k pullup)
* 6 : 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
* 7 : 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
@ -591,7 +591,7 @@
* Note: For Bowden Extruders make this large enough to allow load/unload.
*/
#define PREVENT_LENGTHY_EXTRUDE
#define EXTRUDE_MAXLENGTH 710
#define EXTRUDE_MAXLENGTH 710
//===========================================================================
//======================== Thermal Runaway Protection =======================
@ -977,24 +977,34 @@
//
/**
* Z Probe to nozzle (X,Y) offset, relative to (0, 0).
* Nozzle-to-Probe offsets { X, Y, Z }
*
* In the following example the X and Y offsets are both positive:
* - Use a caliper or ruler to measure the distance from the tip of
* the Nozzle to the center-point of the Probe in the X and Y axes.
* - For the Z offset use your best known value and adjust at runtime.
* - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc.
*
* #define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
* Assuming the typical work area orientation:
* - Probe to RIGHT of the Nozzle has a Positive X offset
* - Probe to LEFT of the Nozzle has a Negative X offset
* - Probe in BACK of the Nozzle has a Positive Y offset
* - Probe in FRONT of the Nozzle has a Negative Y offset
*
* Some examples:
* #define NOZZLE_TO_PROBE_OFFSET { 10, 10, -1 } // Example "1"
* #define NOZZLE_TO_PROBE_OFFSET {-10, 5, -1 } // Example "2"
* #define NOZZLE_TO_PROBE_OFFSET { 5, -5, -1 } // Example "3"
* #define NOZZLE_TO_PROBE_OFFSET {-15,-10, -1 } // Example "4"
*
* +-- BACK ---+
* | |
* L | (+) P | R <-- probe (20,20)
* E | | I
* F | (-) N (+) | G <-- nozzle (10,10)
* T | | H
* | (-) | T
* | |
* | [+] |
* L | 1 | R <-- Example "1" (right+, back+)
* E | 2 | I <-- Example "2" ( left-, back+)
* F |[-] N [+]| G <-- Nozzle
* T | 3 | H <-- Example "3" (right+, front-)
* | 4 | T <-- Example "4" ( left-, front-)
* | [-] |
* O-- FRONT --+
* (0,0)
*
* Specify a Probe position as { X, Y, Z }
*/
#define NOZZLE_TO_PROBE_OFFSET { 37, -20, 0 }
@ -1002,13 +1012,13 @@
// with NOZZLE_AS_PROBE this can be negative for a wider probing area.
#define PROBING_MARGIN 30
// X and Y axis travel speed (mm/m) between probes
#define XY_PROBE_SPEED 1000
// X and Y axis travel speed (mm/min) between probes
#define XY_PROBE_SPEED (1000)
// Feedrate (mm/m) for the first approach when double-probing (MULTIPLE_PROBING == 2)
// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z
// Feedrate (mm/m) for the "accurate" probe of each point
// Feedrate (mm/min) for the "accurate" probe of each point
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)
/**
@ -1079,18 +1089,18 @@
#define Z_ENABLE_ON 0
#define E_ENABLE_ON 0 // For all extruders
// Disables axis stepper immediately when it's not being used.
// Disable axis steppers immediately when they're not being stepped.
// WARNING: When motors turn off there is a chance of losing position accuracy!
#define DISABLE_X false
#define DISABLE_Y false
#define DISABLE_Z false
// Warn on display about possibly reduced accuracy
#define DISABLE_REDUCED_ACCURACY_WARNING
// Turn off the display blinking that warns about possible accuracy reduction
//#define DISABLE_REDUCED_ACCURACY_WARNING
// @section extruder
#define DISABLE_E false // For all extruders
#define DISABLE_E false // Disable the extruder when not stepping
#define DISABLE_INACTIVE_EXTRUDER // Keep only the active extruder enabled
// @section machine
@ -1207,10 +1217,11 @@
*/
//#define FILAMENT_RUNOUT_SENSOR
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
#define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500.
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
// Set one or more commands to execute on filament runout.
// (After 'M412 H' Marlin will ask the host to handle the process.)
@ -1348,7 +1359,7 @@
//#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh
#define MESH_INSET 1 // Set Mesh bounds as an inset region of the bed
#define MESH_INSET 20 // Set Mesh bounds as an inset region of the bed
#define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited.
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
@ -1364,7 +1375,7 @@
//=================================== Mesh ==================================
//===========================================================================
#define MESH_INSET 10 // Set Mesh bounds as an inset region of the bed
#define MESH_INSET 20 // Set Mesh bounds as an inset region of the bed
#define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited.
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
@ -1515,22 +1526,10 @@
/*
MKS Robin EEPROM:
EEPROM_SD
EEPROM_AT24C16
EEPROM_W25Q
*/
#define EEPROM_W25Q
#if ENABLED(EEPROM_AT24C16)
#undef SDCARD_EEPROM_EMULATION
#undef USE_REAL_EEPROM
#undef FLASH_EEPROM_EMULATION
#undef SRAM_EEPROM_EMULATION
#define I2C_EEPROM 1
#define I2C_EEPROM_AT24C16
#define USE_WIRED_EEPROM 1
#define MARLIN_EEPROM_SIZE 1024
#endif
#if ENABLED(EEPROM_W25Q)
#undef SDCARD_EEPROM_EMULATION
#undef USE_REAL_EEPROM
@ -1541,7 +1540,7 @@ EEPROM_W25Q
#define SPI_EEPROM
#define SPI_EEPROM_OFFSET 0x700000
#define USE_WIRED_EEPROM 1
#define MARLIN_EEPROM_SIZE 2048
#define MARLIN_EEPROM_SIZE 4096
#endif
#if ENABLED(EEPROM_SD)
@ -1551,7 +1550,7 @@ EEPROM_W25Q
#undef SRAM_EEPROM_EMULATION
#undef I2C_EEPROM_AT24C16
#undef SPI_EEPROM_W25Q
#undef USE_WIRED_EEPROM
#undef USE_WIRED_EEPROM
#define MARLIN_EEPROM_SIZE 4096
#endif
@ -1676,9 +1675,12 @@ EEPROM_W25Q
// Move the nozzle to the initial position after cleaning
#define NOZZLE_CLEAN_GOBACK
// Enable for a purge/clean station that's always at the gantry height (thus no Z move)
// For a purge/clean station that's always at the gantry height (thus no Z move)
//#define NOZZLE_CLEAN_NO_Z
// For a purge/clean station mounted on the X axis
//#define NOZZLE_CLEAN_NO_Y
// Explicit wipe G-code script applies to a G12 with no arguments.
//#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0"
@ -1715,6 +1717,37 @@ EEPROM_W25Q
*/
//#define PRINTCOUNTER
/**
* Password
*
* Set a numerical password for the printer which can be requested:
*
* - When the printer boots up
* - Upon opening the 'Print from Media' Menu
* - When SD printing is completed or aborted
*
* The following G-codes can be used:
*
* M510 - Lock Printer. Blocks all commands except M511.
* M511 - Unlock Printer.
* M512 - Set, Change and Remove Password.
*
* If you forget the password and get locked out you'll need to re-flash
* the firmware with the feature disabled, reset EEPROM, and (optionally)
* re-flash the firmware again with this feature enabled.
*/
//#define PASSWORD_FEATURE
#if ENABLED(PASSWORD_FEATURE)
#define PASSWORD_LENGTH 4 // (#) Number of digits (1-9). 3 or 4 is recommended
#define PASSWORD_ON_STARTUP
#define PASSWORD_UNLOCK_GCODE // Unlock with the M511 P<password> command. Disable to prevent brute-force attack.
#define PASSWORD_CHANGE_GCODE // Change the password with M512 P<old> S<new>.
//#define PASSWORD_ON_SD_PRINT_MENU // This does not prevent gcodes from running
//#define PASSWORD_AFTER_SD_PRINT_END
//#define PASSWORD_AFTER_SD_PRINT_ABORT
//#include "Configuration_Secure.h" // External file with PASSWORD_DEFAULT_VALUE
#endif
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
@ -1727,7 +1760,7 @@ EEPROM_W25Q
* Select the language to display on the LCD. These languages are available:
*
* en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, hu, it,
* jp_kana, ko_KR, nl, pl, pt, pt_br, ro ru, sk, tr, uk, vi, zh_CN, zh_TW, test
* jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
*
* :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
*/
@ -1758,9 +1791,9 @@ EEPROM_W25Q
#define DISPLAY_CHARSET_HD44780 JAPANESE
/**
* Info Screen Style (0:Classic, 1:Prusa)
* Info Screen Style (0:Classic, 1:Průša)
*
* :[0:'Classic', 1:'Prusa']
* :[0:'Classic', 1:'Průša']
*/
#define LCD_INFO_SCREEN_STYLE 0
@ -2100,7 +2133,7 @@ EEPROM_W25Q
//#define FYSETC_MINI_12864_X_X // Type C/D/E/F. No tunable RGB Backlight by default
//#define FYSETC_MINI_12864_1_2 // Type C/D/E/F. Simple RGB Backlight (always on)
//#define FYSETC_MINI_12864_2_0 // Type A/B. Discreet RGB Backlight
//#define FYSETC_MINI_12864_2_1 // Type A/B. Neopixel RGB Backlight
//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight
//#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight.
//
@ -2162,7 +2195,7 @@ EEPROM_W25Q
//#define OLED_PANEL_TINYBOY2
//
// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER
// MKS OLED 1.3" 128×64 FULL GRAPHICS CONTROLLER
// https://reprap.org/wiki/MKS_12864OLED
//
// Tiny, but very sharp OLED display
@ -2170,6 +2203,13 @@ EEPROM_W25Q
//#define MKS_12864OLED // Uses the SH1106 controller (default)
//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller
//
// Zonestar OLED 128×64 FULL GRAPHICS CONTROLLER
//
//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller
//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default)
//#define ZONESTAR_12864OLED_SSD1306 // 0.96" OLED with SSD1306 controller
//
// Einstart S OLED SSD1306
//
@ -2181,7 +2221,7 @@ EEPROM_W25Q
//#define OVERLORD_OLED
//
// FYSETC OLED 2.42" 128 × 64 FULL GRAPHICS CONTROLLER with WS2812 RGB
// FYSETC OLED 2.42" 128×64 FULL GRAPHICS CONTROLLER with WS2812 RGB
// Where to find : https://www.aliexpress.com/item/4000345255731.html
//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller
@ -2209,6 +2249,16 @@ EEPROM_W25Q
//
//#define TOUCH_UI_FTDI_EVE
//
// Touch-screen LCD for Anycubic printers
//
//#define ANYCUBIC_LCD_I3MEGA
//#define ANYCUBIC_LCD_CHIRON
#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
#define ANYCUBIC_LCD_SERIAL_PORT 3
//#define ANYCUBIC_LCD_DEBUG
#endif
//
// Third-party or vendor-customized controller interfaces.
// Sources should be installed in 'src/lcd/extensible_ui'.
@ -2223,16 +2273,33 @@ EEPROM_W25Q
//=============================== Graphical TFTs ==============================
//=============================================================================
//
// TFT display with optional touch screen
// Color Marlin UI with standard menu system
//
//#define TFT_320x240
//#define TFT_320x240_SPI
//#define TFT_480x320
//#define TFT_480x320_SPI
//
// Skip autodetect and force specific TFT driver
// Mandatory for SPI screens with no MISO line
// Available drivers are: ST7735, ST7789, ST7796, R61505, ILI9328, ILI9341, ILI9488
//
//#define TFT_DRIVER AUTO
//
// SPI display (MKS Robin Nano V2.0, MKS Gen L V2.0)
// Upscaled 128x64 Marlin UI
//
//#define SPI_GRAPHICAL_TFT
//
// FSMC display (MKS Robin, Alfawise U20, JGAurora A5S, REXYZ A1, etc.)
// Upscaled 128x64 Marlin UI
//
#define FSMC_GRAPHICAL_TFT
#if ENABLED(FSMC_GRAPHICAL_TFT)
// #define FSMC_UPSCALE 2 //2x upscaler for 320x240 displays (default)
#define FSMC_UPSCALE 3 //3x upscaler for 480x320 displays
#endif
//
//
// TFT LVGL UI
@ -2244,12 +2311,6 @@ EEPROM_W25Q
//#define TFT_LVGL_UI_FSMC // Robin nano v1.2 uses FSMC
//#define TFT_LVGL_UI_SPI // Robin nano v2.0 uses SPI
//
// Anycubic Mega TFT (AI3M)
//
//#define ANYCUBIC_TFT_MODEL
//#define ANYCUBIC_TFT_DEBUG
//=============================================================================
//============================ Other Controllers ============================
//=============================================================================
@ -2262,20 +2323,20 @@ EEPROM_W25Q
//
// ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8
//
#define TOUCH_BUTTONS
#if ENABLED(TOUCH_BUTTONS)
#define TOUCH_SCREEN
#if ENABLED(TOUCH_SCREEN)
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
#define XPT2046_X_CALIBRATION 12013
#define XPT2046_X_OFFSET -32
#define XPT2046_Y_CALIBRATION -8711
#define XPT2046_Y_OFFSET 256
// #define XPT2046_X_CALIBRATION 12013
// #define XPT2046_X_OFFSET -32
// #define XPT2046_Y_CALIBRATION -8711
// #define XPT2046_Y_OFFSET 256
#endif
//
// RepRapWorld REPRAPWORLD_KEYPAD v1.1
// https://reprapworld.com/?products_details&products_id=202&cPath=1591_1626
// https://reprapworld.com/products/electronics/ramps/keypad_v1_0_fully_assembled/
//
//#define REPRAPWORLD_KEYPAD
//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press
@ -2286,6 +2347,10 @@ EEPROM_W25Q
// @section extras
// Set number of user-controlled fans. Disable to use all board-defined fans.
// :[1,2,3,4,5,6,7,8]
//#define NUM_M106_FANS 1
// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino
//#define FAST_PWM_FAN
@ -2336,13 +2401,13 @@ EEPROM_W25Q
* Adds the M150 command to set the LED (or LED strip) color.
* If pins are PWM capable (e.g., 4, 5, 6, 11) then a range of
* luminance values can be set from 0 to 255.
* For Neopixel LED an overall brightness parameter is also available.
* For NeoPixel LED an overall brightness parameter is also available.
*
* *** CAUTION ***
* LED Strips require a MOSFET Chip between PWM lines and LEDs,
* as the Arduino cannot handle the current the LEDs will require.
* Failure to follow this precaution can destroy your Arduino!
* NOTE: A separate 5V power supply is required! The Neopixel LED needs
* NOTE: A separate 5V power supply is required! The NeoPixel LED needs
* more current than the Arduino 5V linear regulator can produce.
* *** CAUTION ***
*
@ -2359,19 +2424,29 @@ EEPROM_W25Q
//#define RGB_LED_W_PIN -1
#endif
// Support for Adafruit Neopixel LED driver
// Support for Adafruit NeoPixel LED driver
//#define NEOPIXEL_LED
#if ENABLED(NEOPIXEL_LED)
#define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
#define NEOPIXEL_PIN 4 // LED driving pin
//#define NEOPIXEL2_TYPE NEOPIXEL_TYPE
//#define NEOPIXEL2_PIN 5
#define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip, larger of 2 strips if 2 neopixel strips are used
#define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.)
#define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
#define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255)
//#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup
// Use a single Neopixel LED for static (background) lighting
// Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ...
//#define NEOPIXEL2_SEPARATE
#if ENABLED(NEOPIXEL2_SEPARATE)
#define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip
#define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255)
#define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup
#else
//#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel
#endif
// Use a single NeoPixel LED for static (background) lighting
//#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use
//#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W
#endif

83
Marlin/Configuration_adv.h

@ -339,7 +339,7 @@
#if ENABLED(EXTRUDER_RUNOUT_PREVENT)
#define EXTRUDER_RUNOUT_MINTEMP 190
#define EXTRUDER_RUNOUT_SECONDS 30
#define EXTRUDER_RUNOUT_SPEED 1500 // (mm/m)
#define EXTRUDER_RUNOUT_SPEED 1500 // (mm/min)
#define EXTRUDER_RUNOUT_EXTRUDE 5 // (mm)
#endif
@ -487,7 +487,7 @@
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 255 // Set default power-up brightness (0-255, requires PWM pin)
#define CASE_LIGHT_MAX_PWM 255 // Limit pwm
#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu
#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
//#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
//#define CASE_LIGHT_USE_NEOPIXEL // Use Neopixel LED as case light, requires NEOPIXEL_LED.
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
#define CASE_LIGHT_NEOPIXEL_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White }
@ -680,7 +680,7 @@
* Danger: Don't activate 5V mode unless attached to a 5V-tolerant controller!
* V3.0 or 3.1: Set default mode to 5V mode at Marlin startup.
* If disabled, OD mode is the hard-coded default on 3.0
* On startup, Marlin will compare its eeprom to this vale. If the selected mode
* On startup, Marlin will compare its eeprom to this value. If the selected mode
* differs, a mode set eeprom write will be completed at initialization.
* Use the option below to force an eeprom write to a V3.1 probe regardless.
*/
@ -769,7 +769,7 @@
#endif
//
// Add the G35 command to read bed corners to help adjust screws.
// Add the G35 command to read bed corners to help adjust screws. Requires a bed probe.
//
//#define ASSISTED_TRAMMING
#if ENABLED(ASSISTED_TRAMMING)
@ -809,24 +809,30 @@
#define INVERT_Z_STEP_PIN false
#define INVERT_E_STEP_PIN false
// Default stepper release if idle. Set to 0 to deactivate.
// Steppers will shut down DEFAULT_STEPPER_DEACTIVE_TIME seconds after the last move when DISABLE_INACTIVE_? is true.
// Time can be set by M18 and M84.
/**
* Idle Stepper Shutdown
* Set DISABLE_INACTIVE_? 'true' to shut down axis steppers after an idle period.
* The Deactive Time can be overridden with M18 and M84. Set to 0 for No Timeout.
*/
#define DEFAULT_STEPPER_DEACTIVE_TIME 120
#define DISABLE_INACTIVE_X true
#define DISABLE_INACTIVE_Y true
#define DISABLE_INACTIVE_Z true // Set to false if the nozzle will fall down on your printed part when print has finished.
#define DISABLE_INACTIVE_Z true // Set 'false' if the nozzle could fall onto your printed part!
#define DISABLE_INACTIVE_E true
#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate
#define DEFAULT_MINTRAVELFEEDRATE 0.0
// If the Nozzle or Bed falls when the Z stepper is disabled, set its resting position here.
//#define Z_AFTER_DEACTIVATE Z_HOME_POS
#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated
// Minimum time that a segment needs to take if the buffer is emptied
#define DEFAULT_MINSEGMENTTIME 20000 // (µs)
// Default Minimum Feedrates for printing and travel moves
#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S.
#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T.
// Slow down the machine if the look ahead buffer is (by default) half full.
// Minimum time that a segment needs to take as the buffer gets emptied
#define DEFAULT_MINSEGMENTTIME 20000 // (µs) Set with M205 B.
// Slow down the machine if the lookahead buffer is (by default) half full.
// Increase the slowdown divisor for larger buffer sizes.
#define SLOWDOWN
#if ENABLED(SLOWDOWN)
@ -877,7 +883,7 @@
// increments while checking for the contact to be broken.
#define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm)
#define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm)
#define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_SPEED_SLOW // (mm/m)
#define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_SPEED_SLOW // (mm/min)
#endif
#endif
#endif
@ -903,9 +909,9 @@
#define CALIBRATION_MEASUREMENT_RESOLUTION 0.01 // mm
#define CALIBRATION_FEEDRATE_SLOW 60 // mm/m
#define CALIBRATION_FEEDRATE_FAST 1200 // mm/m
#define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/m
#define CALIBRATION_FEEDRATE_SLOW 60 // mm/min
#define CALIBRATION_FEEDRATE_FAST 1200 // mm/min
#define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/min
// The following parameters refer to the conical section of the nozzle tip.
#define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // mm
@ -1019,7 +1025,7 @@
// @section lcd
#if EITHER(ULTIPANEL, EXTENSIBLE_UI)
#define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 60 } // Feedrates for manual moves along X, Y, Z, E from panel
#define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
#define SHORT_MANUAL_Z_MOVE 0.025 // (mm) Smallest manual Z move (< 0.1mm)
#if ENABLED(ULTIPANEL)
#define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position"
@ -1059,6 +1065,7 @@
//#define LED_CONTROL_MENU
#if ENABLED(LED_CONTROL_MENU)
#define LED_COLOR_PRESETS // Enable the Preset Color menu option
//#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option
#if ENABLED(LED_COLOR_PRESETS)
#define LED_USER_PRESET_RED 255 // User defined RED value
#define LED_USER_PRESET_GREEN 128 // User defined GREEN value
@ -1067,6 +1074,14 @@
#define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity
//#define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup
#endif
#if ENABLED(NEO2_COLOR_PRESETS)
#define NEO2_USER_PRESET_RED 255 // User defined RED value
#define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value
#define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value
#define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value
#define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity
//#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip
#endif
#endif
#endif // HAS_LCD_MENU
@ -1131,7 +1146,7 @@
//#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files
#define EVENT_GCODE_SD_STOP "G28XY" // G-code to run on Stop Print (e.g., "G28XY" or "G27")
#define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27")
#if ENABLED(PRINTER_EVENT_LEDS)
#define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination
@ -1276,7 +1291,7 @@
#endif
// Add an optimized binary file transfer mode, initiated with 'M28 B1'
//#define BINARY_FILE_TRANSFER
#define BINARY_FILE_TRANSFER
/**
* Set this option to one of the following (or the board's defaults apply):
@ -1509,9 +1524,9 @@
#endif
//
// FSMC Graphical TFT
// FSMC / SPI Graphical TFT
//
#if ENABLED(FSMC_GRAPHICAL_TFT)
#if TFT_SCALED_DOGLCD
#define TFT_MARLINUI_COLOR COLOR_WHITE // White
#define TFT_MARLINBG_COLOR COLOR_BLACK // Black
#define TFT_DISABLED_COLOR 0x0003 // Almost black
@ -1978,13 +1993,13 @@
// Load / Unload
#define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart, fine tune by LCD/Gcode)
#define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/m) (Unloading)
#define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/m) (On SINGLENOZZLE or Bowden loading must be slowed down)
#define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading)
#define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down)
// Longer prime to clean out a SINGLENOZZLE
#define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length
#define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/m) Extra priming feedrate
#define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm/m) Retract before cooling for less stringing, better wipe, etc.
#define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate
#define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm/min) Retract before cooling for less stringing, better wipe, etc.
// Cool after prime to reduce stringing
#define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip
@ -2020,7 +2035,7 @@
//#define TOOLCHANGE_PARK
#if ENABLED(TOOLCHANGE_PARK)
#define TOOLCHANGE_PARK_XY { X_MIN_POS + 10, Y_MIN_POS + 10 }
#define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/m)
#define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/min)
//#define TOOLCHANGE_PARK_X_ONLY // X axis only move
//#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move
#endif
@ -2417,7 +2432,7 @@
* CHOPPER_DEFAULT_24V
* CHOPPER_DEFAULT_36V
* CHOPPER_09STEP_24V // 0.9 degree steppers (24V)
* CHOPPER_PRUSAMK3_24V // Imported parameters from the official Prusa firmware for MK3 (24V)
* CHOPPER_PRUSAMK3_24V // Imported parameters from the official Průša firmware for MK3 (24V)
* CHOPPER_MARLIN_119 // Old defaults from Marlin v1.1.9
*
* Define you own with
@ -2844,7 +2859,7 @@
//#define SPINDLE_FEATURE
//#define LASER_FEATURE
#if EITHER(SPINDLE_FEATURE, LASER_FEATURE)
#define SPINDLE_LASER_ACTIVE_HIGH false // Set to "true" if the on/off function is active HIGH
#define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if the on/off function is active HIGH
#define SPINDLE_LASER_PWM true // Set to "true" if your controller supports setting the speed/power
#define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower
@ -3144,7 +3159,7 @@
//#define GCODE_MOTION_MODES // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc.
// Enable and set a (default) feedrate for all G0 moves
//#define G0_FEEDRATE 3000 // (mm/m)
//#define G0_FEEDRATE 3000 // (mm/min)
#ifdef G0_FEEDRATE
//#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode
#endif
@ -3390,7 +3405,7 @@
#endif
/**
* Prusa Multi-Material Unit v2
* Průša Multi-Material Unit v2
* Enable in Configuration.h
*/
#if ENABLED(PRUSA_MMU2)
@ -3414,7 +3429,7 @@
//#define MMU2_MENUS
#if ENABLED(MMU2_MENUS)
// Settings for filament load / unload from the LCD menu.
// This is for Prusa MK3-style extruders. Customize for your hardware.
// This is for Průša MK3-style extruders. Customize for your hardware.
#define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0
#define MMU2_LOAD_TO_NOZZLE_SEQUENCE \
{ 7.2, 1145 }, \
@ -3440,7 +3455,7 @@
/**
* MMU Extruder Sensor
*
* Support for a Prusa (or other) IR Sensor to detect filament near the extruder
* Support for a Průša (or other) IR Sensor to detect filament near the extruder
* and make loading more reliable. Suitable for an extruder equipped with a filament
* sensor less than 38mm from the gears.
*
@ -3462,7 +3477,7 @@
#if ENABLED(PRUSA_MMU2_S_MODE)
#define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries)
#define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/m)
#define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min)
#define MMU2_CAN_LOAD_SEQUENCE \
{ 0.1, MMU2_CAN_LOAD_FEEDRATE }, \
{ 60.0, MMU2_CAN_LOAD_FEEDRATE }, \

2
Marlin/Version.h

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

11
Marlin/src/HAL/AVR/HAL.h

@ -120,6 +120,17 @@ typedef int8_t pin_t;
#define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.get_tx_buffer_free
#endif
#ifdef ANYCUBIC_LCD_SERIAL_PORT
#if !WITHIN(ANYCUBIC_LCD_SERIAL_PORT, -1, 3)
#error "ANYCUBIC_LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#elif ANYCUBIC_LCD_SERIAL_PORT == SERIAL_PORT
#error "ANYCUBIC_LCD_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
#elif defined(SERIAL_PORT_2) && ANYCUBIC_LCD_SERIAL_PORT == SERIAL_PORT_2
#error "ANYCUBIC_LCD_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
#endif
#define ANYCUBIC_LCD_SERIAL anycubicLcdSerial
#endif
// ------------------------
// Public functions
// ------------------------

18
Marlin/src/HAL/AVR/MarlinSerial.cpp

@ -792,6 +792,24 @@
#endif
#ifdef ANYCUBIC_LCD_SERIAL_PORT
ISR(SERIAL_REGNAME(USART,ANYCUBIC_LCD_SERIAL_PORT,_RX_vect)) {
MarlinSerial<AnycubicLcdSerialCfg<ANYCUBIC_LCD_SERIAL_PORT>>::store_rxd_char();
}
ISR(SERIAL_REGNAME(USART,ANYCUBIC_LCD_SERIAL_PORT,_UDRE_vect)) {
MarlinSerial<AnycubicLcdSerialCfg<ANYCUBIC_LCD_SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<AnycubicLcdSerialCfg<ANYCUBIC_LCD_SERIAL_PORT>>;
// Instantiate
MarlinSerial<AnycubicLcdSerialCfg<ANYCUBIC_LCD_SERIAL_PORT>> anycubicLcdSerial;
#endif
// For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial;

17
Marlin/src/HAL/AVR/MarlinSerial.h

@ -312,6 +312,23 @@
extern MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>> internalDgusSerial;
#endif
#ifdef ANYCUBIC_LCD_SERIAL_PORT
template <uint8_t serial>
struct AnycubicLcdSerialCfg {
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = 64;
static constexpr unsigned int TX_SIZE = 128;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = false;
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_OVERRUNS = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
};
extern MarlinSerial<AnycubicLcdSerialCfg<ANYCUBIC_LCD_SERIAL_PORT>> anycubicLcdSerial;
#endif
// Use the UART for Bluetooth in AT90USB configurations
#if defined(USBCON) && ENABLED(BLUETOOTH)
extern HardwareSerial bluetoothSerial;

8
Marlin/src/HAL/AVR/ServoTimers.h

@ -59,10 +59,12 @@
// Say which 16 bit timers can be used and in what order
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//#define _useTimer1
#define _useTimer3
#define _useTimer4
#if !HAS_MOTOR_CURRENT_PWM
#define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos.
#if NUM_SERVOS > SERVOS_PER_TIMER
#define _useTimer3
#if !HAS_MOTOR_CURRENT_PWM && SERVOS > 2 * SERVOS_PER_TIMER
#define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos.
#endif
#endif
#elif defined(__AVR_ATmega32U4__)
#define _useTimer3

4
Marlin/src/HAL/AVR/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/AVR."
#endif

3
Marlin/src/HAL/AVR/inc/SanityCheck.h

@ -36,9 +36,10 @@
* Sanity checks for Spindle / Laser PWM
*/
#if ENABLED(SPINDLE_LASER_PWM)
#include "../ServoTimers.h" // Needed to check timer availability (_useTimer3)
#if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
#elif NUM_SERVOS > 0 && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
#elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
#endif
#elif defined(SPINDLE_LASER_FREQUENCY)

1
Marlin/src/HAL/DUE/HAL.cpp

@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**

4
Marlin/src/HAL/DUE/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/DUE."
#endif

2
Marlin/src/HAL/DUE/usb/arduino_due_x.h

@ -93,5 +93,5 @@
#define USB_VBOF_GPIO (PIO_PB10_IDX)
#define USB_VBOF_FLAGS (PIO_PERIPH_A | PIO_DEFAULT)
/*! Active level of the USB_VBOF output pin. */
#define USB_VBOF_ACTIVE_LEVEL LOW
#define USB_VBOF_ACTIVE_STATE LOW
/* ------------------------------------------------------------------------ */

4
Marlin/src/HAL/ESP32/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/ESP32."
#endif

1
Marlin/src/HAL/ESP32/ota.cpp

@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32

2
Marlin/src/HAL/HAL.h

@ -38,7 +38,7 @@
// String helper
#ifndef PGMSTR
#define PGMSTR(NAM,STR) constexpr char NAM[] = STR
#define PGMSTR(NAM,STR) const char NAM[] = STR
#endif
inline void watchdog_refresh() {

4
Marlin/src/HAL/LINUX/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/LINUX."
#endif

252
Marlin/src/HAL/LPC1768/HAL_SPI.cpp

@ -30,7 +30,7 @@
*/
/**
* Hardware SPI and a software SPI implementations are included in this file.
* Hardware SPI and Software SPI implementations are included in this file.
* The hardware SPI runs faster and has higher throughput but is not compatible
* with some LCD interfaces/adapters.
*
@ -51,6 +51,10 @@
#include "../../inc/MarlinConfig.h"
#include <SPI.h>
// Hardware SPI and SPIClass
#include <lpc17xx_pinsel.h>
#include <lpc17xx_clkpwr.h>
// ------------------------
// Public functions
// ------------------------
@ -96,12 +100,6 @@
#else
// Hardware SPI
#include <lpc17xx_pinsel.h>
#include <lpc17xx_ssp.h>
#include <lpc17xx_clkpwr.h>
// decide which HW SPI device to use
#ifndef LPC_HW_SPI_DEV
#if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09)
@ -114,7 +112,7 @@
#endif
#endif
#endif
#if (LPC_HW_SPI_DEV == 0)
#if LPC_HW_SPI_DEV == 0
#define LPC_SSPn LPC_SSP0
#else
#define LPC_SSPn LPC_SSP1
@ -192,7 +190,7 @@
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
}
static uint8_t spiTransfer(uint8_t b) {
uint8_t spiTransfer(uint8_t b) {
return doio(b);
}
@ -211,30 +209,236 @@
#endif // LPC_SOFTWARE_SPI
void SPIClass::begin() { spiBegin(); }
/**
* @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
*/
static inline void waitSpiTxEnd(LPC_SSP_TypeDef *spi_d) {
while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1
while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0
}
SPIClass::SPIClass(uint8_t device) {
// Init things specific to each SPI device
// clock divider setup is a bit of hack, and needs to be improved at a later date.
PINSEL_CFG_Type PinCfg; // data structure to hold init values
#if BOARD_NR_SPI >= 1
_settings[0].spi_d = LPC_SSP0;
// _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
PinCfg.Funcnum = 2;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_SCK_PIN);
PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_SCK_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(BOARD_SPI1_SCK_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_MISO_PIN);
PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_MISO_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_INPUT(BOARD_SPI1_MISO_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_MOSI_PIN);
PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_MOSI_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(BOARD_SPI1_MOSI_PIN);
#endif
#if BOARD_NR_SPI >= 2
_settings[1].spi_d = LPC_SSP1;
// _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
PinCfg.Funcnum = 2;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_SCK_PIN);
PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_SCK_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(BOARD_SPI2_SCK_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_MISO_PIN);
PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_MISO_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_INPUT(BOARD_SPI2_MISO_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_MOSI_PIN);
PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_MOSI_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(BOARD_SPI2_MOSI_PIN);
#endif
setModule(device);
/* Initialize GPDMA controller */
//TODO: call once in the constructor? or each time?
GPDMA_Init();
}
void SPIClass::begin() {
updateSettings();
SSP_Cmd(_currentSetting->spi_d, ENABLE); // start SSP running
}
void SPIClass::beginTransaction(const SPISettings &cfg) {
uint8_t spiRate;
switch (cfg.spiRate()) {
case 8000000: spiRate = 0; break;
case 4000000: spiRate = 1; break;
case 2000000: spiRate = 2; break;
case 1000000: spiRate = 3; break;
case 500000: spiRate = 4; break;
case 250000: spiRate = 5; break;
case 125000: spiRate = 6; break;
default: spiRate = 2; break;
}
spiInit(spiRate);
setBitOrder(cfg.bitOrder);
setDataMode(cfg.dataMode);
setDataSize(cfg.dataSize);
//setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
begin();
}
uint8_t SPIClass::transfer(const uint8_t B) { return spiTransfer(B); }
uint8_t SPIClass::transfer(const uint16_t b) {
/* send and receive a single byte */
SSP_ReceiveData(_currentSetting->spi_d); // read any previous data
SSP_SendData(_currentSetting->spi_d, b);
waitSpiTxEnd(_currentSetting->spi_d); // wait for it to finish
return SSP_ReceiveData(_currentSetting->spi_d);
}
uint16_t SPIClass::transfer16(const uint16_t data) {
return (transfer((data >> 8) & 0xFF) << 8)
| (transfer(data & 0xFF) & 0xFF);
}
SPIClass SPI;
void SPIClass::end() {
// SSP_Cmd(_currentSetting->spi_d, DISABLE); // stop device or SSP_DeInit?
SSP_DeInit(_currentSetting->spi_d);
}
void SPIClass::send(uint8_t data) {
SSP_SendData(_currentSetting->spi_d, data);
}
void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
//TODO: LPC dma can only write 0xFFF bytes at once.
GPDMA_Channel_CFG_Type GPDMACfg;
/* Configure GPDMA channel 0 -------------------------------------------------------------*/
/* DMA Channel 0 */
GPDMACfg.ChannelNum = 0;
// Source memory
GPDMACfg.SrcMemAddr = (uint32_t)buf;
// Destination memory - Not used
GPDMACfg.DstMemAddr = 0;
// Transfer size
GPDMACfg.TransferSize = (minc ? length : 1);
// Transfer width
GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE;
// Transfer type
GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P;
// Source connection - unused
GPDMACfg.SrcConn = 0;
// Destination connection
GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx;
GPDMACfg.DMALLI = 0;
// Enable dma on SPI
SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
// if minc=false, I'm repeating the same byte 'length' times, as I could not find yet how do GPDMA without memory increment
do {
// Setup channel with given parameter
GPDMA_Setup(&GPDMACfg);
// enabled dma
GPDMA_ChannelCmd(0, ENABLE);
// wait data transfer
while (!GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)) { }
// clear err and int
GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
// dma disable
GPDMA_ChannelCmd(0, DISABLE);
--length;
} while (!minc && length > 0);
waitSpiTxEnd(_currentSetting->spi_d);
SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE);
}
uint16_t SPIClass::read() {
return SSP_ReceiveData(_currentSetting->spi_d);
}
void SPIClass::read(uint8_t *buf, uint32_t len) {
for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF);
}
void SPIClass::setClock(uint32_t clock) {
_currentSetting->clock = clock;
}
void SPIClass::setModule(uint8_t device) {
_currentSetting = &_settings[device - 1];// SPI channels are called 1 2 and 3 but the array is zero indexed
}
void SPIClass::setBitOrder(uint8_t bitOrder) {
_currentSetting->bitOrder = bitOrder;
}
void SPIClass::setDataMode(uint8_t dataMode) {
_currentSetting->dataSize = dataMode;
}
void SPIClass::setDataSize(uint32_t ds) {
_currentSetting->dataSize = ds;
}
/**
* Set up/tear down
*/
void SPIClass::updateSettings() {
//SSP_DeInit(_currentSetting->spi_d); //todo: need force de init?!
// divide PCLK by 2 for SSP0
CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
SSP_CFG_Type HW_SPI_init; // data structure to hold init values
SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode
HW_SPI_init.ClockRate = _currentSetting->clock;
HW_SPI_init.Databit = _currentSetting->dataSize;
/**
* SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge
* 0 0 0 Falling Rising
* 1 0 1 Rising Falling
* 2 1 0 Rising Falling
* 3 1 1 Falling Rising
*/
switch (_currentSetting->dataMode) {
case SPI_MODE0:
HW_SPI_init.CPHA = SSP_CPHA_FIRST;
HW_SPI_init.CPOL = SSP_CPOL_HI;
break;
case SPI_MODE1:
HW_SPI_init.CPHA = SSP_CPHA_SECOND;
HW_SPI_init.CPOL = SSP_CPOL_HI;
break;
case SPI_MODE2:
HW_SPI_init.CPHA = SSP_CPHA_FIRST;
HW_SPI_init.CPOL = SSP_CPOL_LO;
break;
case SPI_MODE3:
HW_SPI_init.CPHA = SSP_CPHA_SECOND;
HW_SPI_init.CPOL = SSP_CPOL_LO;
break;
default:
break;
}
// TODO: handle bitOrder
SSP_Init(_currentSetting->spi_d, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers
}
#if MISO_PIN == BOARD_SPI1_MISO_PIN
SPIClass SPI(1);
#elif MISO_PIN == BOARD_SPI2_MISO_PIN
SPIClass SPI(2);
#endif
#endif // TARGET_LPC1768

11
Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h

@ -20,3 +20,14 @@
*
*/
#pragma once
#if HAS_FSMC_TFT
#error "Sorry! FSMC TFT displays are not current available for HAL/LPC1768."
#endif
// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
#undef TOUCH_SCREEN
#undef TOUCH_SCREEN_CALIBRATION
#define HAS_TOUCH_XPT2046 1
#endif

140
Marlin/src/HAL/LPC1768/include/SPI.h

@ -24,25 +24,139 @@
#include "../../shared/HAL_SPI.h"
#include <stdint.h>
#include <lpc17xx_ssp.h>
#include <lpc17xx_gpdma.h>
#define MSBFIRST 1
#define SPI_MODE3 0
//#define MSBFIRST 1
#define SPI_MODE0 0
#define SPI_MODE1 1
#define SPI_MODE2 2
#define SPI_MODE3 3
#define DATA_SIZE_8BIT SSP_DATABIT_8
#define DATA_SIZE_16BIT SSP_DATABIT_16
#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
#define BOARD_NR_SPI 2
//#define BOARD_SPI1_NSS_PIN PA4 ?!
#define BOARD_SPI1_SCK_PIN P0_15
#define BOARD_SPI1_MISO_PIN P0_17
#define BOARD_SPI1_MOSI_PIN P0_18
//#define BOARD_SPI2_NSS_PIN PB12 ?!
#define BOARD_SPI2_SCK_PIN P0_07
#define BOARD_SPI2_MISO_PIN P0_08
#define BOARD_SPI2_MOSI_PIN P0_09
class SPISettings {
public:
SPISettings(uint32_t speed, int, int) : spi_speed(speed) {};
uint32_t spiRate() const { return spi_speed; }
private:
uint32_t spi_speed;
public:
SPISettings(uint32_t speed, int, int) : spi_speed(speed) {};
SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
if (__builtin_constant_p(inClock))
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
else
init_MightInline(inClock, inBitOrder, inDataMode, inDataSize);
}
SPISettings() {
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
}
uint32_t spiRate() const { return spi_speed; }
private:
void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
}
void init_AlwaysInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) {
clock = inClock;
bitOrder = inBitOrder;
dataMode = inDataMode;
dataSize = inDataSize;
}
uint32_t spi_speed;
uint32_t clock;
uint32_t dataSize;
//uint32_t clockDivider;
uint8_t bitOrder;
uint8_t dataMode;
LPC_SSP_TypeDef *spi_d;
friend class SPIClass;
};
/**
* @brief Wirish SPI interface.
*
* This is the same interface is available across HAL
*
* This implementation uses software slave management, so the caller
* is responsible for controlling the slave select line.
*/
class SPIClass {
public:
void begin();
void beginTransaction(const SPISettings&);
void endTransaction() {};
uint8_t transfer(uint8_t data);
uint16_t transfer16(uint16_t data);
public:
/**
* @param spiPortNumber Number of the SPI port to manage.
*/
SPIClass(uint8_t spiPortNumber);
/**
* Select and configure the current selected SPI device to use
*/
void begin();
/**
* Disable the current SPI device
*/
void end();
void beginTransaction(const SPISettings&);
void endTransaction() {};
// Transfer using 1 "Data Size"
uint8_t transfer(uint16_t data);
// Transfer 2 bytes in 8 bit mode
uint16_t transfer16(uint16_t data);
void send(uint8_t data);
uint16_t read();
void read(uint8_t *buf, uint32_t len);
void dmaSend(void *buf, uint16_t length, bool minc);
/**
* @brief Sets the number of the SPI peripheral to be used by
* this HardwareSPI instance.
*
* @param spi_num Number of the SPI port. 1-2 in low density devices
* or 1-3 in high density devices.
*/
void setModule(uint8_t device);
void setClock(uint32_t clock);
void setBitOrder(uint8_t bitOrder);
void setDataMode(uint8_t dataMode);
void setDataSize(uint32_t ds);
inline uint32_t getDataSize() { return _currentSetting->dataSize; }
private:
SPISettings _settings[BOARD_NR_SPI];
SPISettings *_currentSetting;
void updateSettings();
};
extern SPIClass SPI;

153
Marlin/src/HAL/LPC1768/tft/tft_spi.cpp

@ -0,0 +1,153 @@
/**
* 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 HAS_SPI_TFT
#include "tft_spi.h"
//TFT_SPI tft;
SPIClass TFT_SPI::SPIx(1);
#define TFT_CS_H WRITE(TFT_CS_PIN, HIGH)
#define TFT_CS_L WRITE(TFT_CS_PIN, LOW)
#define TFT_DC_H WRITE(TFT_DC_PIN, HIGH)
#define TFT_DC_L WRITE(TFT_DC_PIN, LOW)
#define TFT_RST_H WRITE(TFT_RESET_PIN, HIGH)
#define TFT_RST_L WRITE(TFT_RESET_PIN, LOW)
#define TFT_BLK_H WRITE(TFT_BACKLIGHT_PIN, HIGH)
#define TFT_BLK_L WRITE(TFT_BACKLIGHT_PIN, LOW)
void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET)
SET_OUTPUT(TFT_RESET_PIN);
TFT_RST_H;
delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
SET_OUTPUT(TFT_BACKLIGHT_PIN);
TFT_BLK_H;
#endif
SET_OUTPUT(TFT_DC_PIN);
SET_OUTPUT(TFT_CS_PIN);
TFT_DC_H;
TFT_CS_H;
/**
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/
#if 0
#if SPI_DEVICE == 1
#define SPI_CLOCK_MAX SPI_CLOCK_DIV4
#else
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
#endif
uint8_t clock;
uint8_t spiRate = SPI_FULL_SPEED;
switch (spiRate) {
case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break;
case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break;
case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break;
case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
}
#endif
#if TFT_MISO_PIN == BOARD_SPI1_MISO_PIN
SPIx.setModule(1);
#elif TFT_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIx.setModule(2);
#endif
SPIx.setClock(SPI_CLOCK_MAX);
SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0);
}
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.setDataSize(DataSize);
SPIx.begin();
TFT_CS_L;
}
uint32_t TFT_SPI::GetID() {
uint32_t id;
id = ReadID(LCD_READ_ID);
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = ReadID(LCD_READ_ID4);
return id;
}
uint32_t TFT_SPI::ReadID(uint16_t Reg) {
uint32_t data = 0;
#if PIN_EXISTS(TFT_MISO)
uint8_t d = 0;
SPIx.setDataSize(DATASIZE_8BIT);
SPIx.setClock(SPI_CLOCK_DIV64);
SPIx.begin();
TFT_CS_L;
WriteReg(Reg);
LOOP_L_N(i, 4) {
SPIx.read((uint8_t*)&d, 1);
data = (data << 8) | d;
}
DataTransferEnd();
SPIx.setClock(SPI_CLOCK_MAX);
#endif
return data >> 7;
}
bool TFT_SPI::isBusy() {
return false;
}
void TFT_SPI::Abort() {
DataTransferEnd();
}
void TFT_SPI::Transmit(uint16_t Data) {
SPIx.transfer(Data);
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DataTransferBegin(DATASIZE_16BIT); //16
TFT_DC_H;
SPIx.dmaSend(Data, Count, MemoryIncrease);
DataTransferEnd();
}
#endif // HAS_SPI_TFT

77
Marlin/src/HAL/LPC1768/tft/tft_spi.h

@ -0,0 +1,77 @@
/**
* 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"
#include <SPI.h>
#include <lpc17xx_ssp.h>
// #include <lpc17xx_gpdma.h>
#ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT SSP_DATABIT_8
#define DATASIZE_16BIT SSP_DATABIT_16
#define TFT_IO TFT_SPI
#define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0
class TFT_SPI {
private:
static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
static SPIClass SPIx;
static void Init();
static uint32_t GetID();
static bool isBusy();
static void Abort();
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT);
static void DataTransferEnd() { OUT_WRITE(TFT_CS_PIN, HIGH); SPIx.end(); };
static void DataTransferAbort();
static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { OUT_WRITE(TFT_A0_PIN, LOW); Transmit(Reg); OUT_WRITE(TFT_A0_PIN, HIGH); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
// static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
//LPC dma can only write 0xFFF bytes at once.
#define MAX_DMA_SIZE (0xFFF - 1)
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > MAX_DMA_SIZE ? MAX_DMA_SIZE : Count);
Count = Count > MAX_DMA_SIZE ? Count - MAX_DMA_SIZE : 0;
}
#undef MAX_DMA_SIZE
}
};

129
Marlin/src/HAL/LPC1768/tft/xpt2046.cpp

@ -0,0 +1,129 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046
#include "xpt2046.h"
#include <SPI.h>
uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; }
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
#include <SPI.h>
SPIClass XPT2046::SPIx(TOUCH_BUTTONS_HW_SPI_DEVICE);
static void touch_spi_init(uint8_t spiRate) {
XPT2046::SPIx.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE);
XPT2046::SPIx.setClock(SPI_CLOCK_DIV128);
XPT2046::SPIx.setBitOrder(MSBFIRST);
XPT2046::SPIx.setDataMode(SPI_MODE0);
XPT2046::SPIx.setDataSize(DATA_SIZE_8BIT);
}
#endif
void XPT2046::Init() {
SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN);
OUT_WRITE(TOUCH_CS_PIN, HIGH);
#if PIN_EXISTS(TOUCH_INT)
// Optional Pendrive interrupt pin
SET_INPUT(TOUCH_INT_PIN);
#endif
TERN_(TOUCH_BUTTONS_HW_SPI, touch_spi_init(SPI_SPEED_6));
// Read once to enable pendrive status pin
getRawData(XPT2046_X);
}
bool XPT2046::isTouched() {
return isBusy() ? false : (
#if PIN_EXISTS(TOUCH_INT)
READ(TOUCH_INT_PIN) != HIGH
#else
getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD
#endif
);
}
bool XPT2046::getRawPoint(int16_t *x, int16_t *y) {
if (isBusy()) return false;
if (!isTouched()) return false;
*x = getRawData(XPT2046_X);
*y = getRawData(XPT2046_Y);
SERIAL_ECHOLNPAIR("X: ", *x, ", Y: ", *y);
return isTouched();
}
uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) {
uint16_t data[3];
DataTransferBegin();
TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.begin());
for (uint16_t i = 0; i < 3 ; i++) {
IO(coordinate);
data[i] = (IO() << 4) | (IO() >> 4);
}
TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.end());
DataTransferEnd();
uint16_t delta01 = delta(data[0], data[1]),
delta02 = delta(data[0], data[2]),
delta12 = delta(data[1], data[2]);
if (delta01 > delta02 || delta01 > delta12)
data[delta02 > delta12 ? 0 : 1] = data[2];
return (data[0] + data[1]) >> 1;
}
uint16_t XPT2046::IO(uint16_t data) {
return TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data);
}
extern uint8_t spiTransfer(uint8_t b);
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
uint16_t XPT2046::HardwareIO(uint16_t data) {
return SPIx.transfer(data & 0xFF);
}
#endif
uint16_t XPT2046::SoftwareIO(uint16_t data) {
uint16_t result = 0;
for (uint8_t j = 0x80; j; j >>= 1) {
WRITE(TOUCH_SCK_PIN, LOW);
WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW);
if (READ(TOUCH_MISO_PIN)) result |= j;
WRITE(TOUCH_SCK_PIN, HIGH);
}
WRITE(TOUCH_SCK_PIN, LOW);
return result;
}
#endif // HAS_TFT_XPT2046

80
Marlin/src/HAL/LPC1768/tft/xpt2046.h

@ -0,0 +1,80 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 ENABLED(TOUCH_BUTTONS_HW_SPI)
#include <SPI.h>
#endif
#ifndef TOUCH_MISO_PIN
#define TOUCH_MISO_PIN MISO_PIN
#endif
#ifndef TOUCH_MOSI_PIN
#define TOUCH_MOSI_PIN MOSI_PIN
#endif
#ifndef TOUCH_SCK_PIN
#define TOUCH_SCK_PIN SCK_PIN
#endif
#ifndef TOUCH_CS_PIN
#define TOUCH_CS_PIN CS_PIN
#endif
#ifndef TOUCH_INT_PIN
#define TOUCH_INT_PIN -1
#endif
#define XPT2046_DFR_MODE 0x00
#define XPT2046_SER_MODE 0x04
#define XPT2046_CONTROL 0x80
enum XPTCoordinate : uint8_t {
XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
};
#if !defined(XPT2046_Z1_THRESHOLD)
#define XPT2046_Z1_THRESHOLD 10
#endif
class XPT2046 {
private:
static bool isBusy() { return false; }
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
static inline void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static uint16_t HardwareIO(uint16_t data);
#endif
static uint16_t SoftwareIO(uint16_t data);
static uint16_t IO(uint16_t data = 0);
public:
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static SPIClass SPIx;
#endif
static void Init();
static bool getRawPoint(int16_t *x, int16_t *y);
};

0
Marlin/src/HAL/LPC1768/upload_extra_script.py

27
Marlin/src/HAL/SAMD51/endstop_interrupts.h

@ -126,82 +126,83 @@
void endstop_ISR() { endstops.update(); }
void setup_endstop_interrupts() {
#define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE)
#if HAS_X_MAX
#if !AVAILABLE_EILINE(X_MAX_PIN)
#error "X_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(X_MAX_PIN, endstop_ISR, CHANGE);
_ATTACH(X_MAX_PIN);
#endif
#if HAS_X_MIN
#if !AVAILABLE_EILINE(X_MIN_PIN)
#error "X_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(X_MIN_PIN, endstop_ISR, CHANGE);
_ATTACH(X_MIN_PIN);
#endif
#if HAS_Y_MAX
#if !AVAILABLE_EILINE(Y_MAX_PIN)
#error "Y_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(Y_MAX_PIN, endstop_ISR, CHANGE);
_ATTACH(Y_MAX_PIN);
#endif
#if HAS_Y_MIN
#if !AVAILABLE_EILINE(Y_MIN_PIN)
#error "Y_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(Y_MIN_PIN, endstop_ISR, CHANGE);
_ATTACH(Y_MIN_PIN);
#endif
#if HAS_Z_MAX
#if !AVAILABLE_EILINE(Z_MAX_PIN)
#error "Z_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(Z_MAX_PIN, endstop_ISR, CHANGE);
_ATTACH(Z_MAX_PIN);
#endif
#if HAS_Z_MIN
#if !AVAILABLE_EILINE(Z_MIN_PIN)
#error "Z_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(Z_MIN_PIN, endstop_ISR, CHANGE);
_ATTACH(Z_MIN_PIN);
#endif
#if HAS_Z2_MAX
#if !AVAILABLE_EILINE(Z2_MAX_PIN)
#error "Z2_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(Z2_MAX_PIN, endstop_ISR, CHANGE);
_ATTACH(Z2_MAX_PIN);
#endif
#if HAS_Z2_MIN
#if !AVAILABLE_EILINE(Z2_MIN_PIN)
#error "Z2_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(Z2_MIN_PIN, endstop_ISR, CHANGE);
_ATTACH(Z2_MIN_PIN);
#endif
#if HAS_Z3_MAX
#if !AVAILABLE_EILINE(Z3_MAX_PIN)
#error "Z3_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(Z3_MAX_PIN, endstop_ISR, CHANGE);
_ATTACH(Z3_MAX_PIN);
#endif
#if HAS_Z3_MIN
#if !AVAILABLE_EILINE(Z3_MIN_PIN)
#error "Z3_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(Z3_MIN_PIN, endstop_ISR, CHANGE);
_ATTACH(Z3_MIN_PIN);
#endif
#if HAS_Z4_MAX
#if !AVAILABLE_EILINE(Z4_MAX_PIN)
#error "Z4_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(Z4_MAX_PIN, endstop_ISR, CHANGE);
_ATTACH(Z4_MAX_PIN);
#endif
#if HAS_Z4_MIN
#if !AVAILABLE_EILINE(Z4_MIN_PIN)
#error "Z4_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(Z4_MIN_PIN, endstop_ISR, CHANGE);
_ATTACH(Z4_MIN_PIN);
#endif
#if HAS_Z_MIN_PROBE_PIN
#if !AVAILABLE_EILINE(Z_MIN_PROBE_PIN)
#error "Z_MIN_PROBE_PIN has no EXTINT line available."
#endif
attachInterrupt(Z_MIN_PROBE_PIN, endstop_ISR, CHANGE);
_ATTACH(Z_MIN_PROBE_PIN);
#endif
}

4
Marlin/src/HAL/SAMD51/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/SAMD51."
#endif

5
Marlin/src/HAL/STM32/HAL.h

@ -213,5 +213,10 @@ uint16_t HAL_adc_get_result();
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#ifdef STM32F1xx
#define JTAG_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE)
#define JTAGSWD_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE)
#endif
#define PLATFORM_M997_SUPPORT
void flashFirmware(const int16_t);

73
Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp

@ -76,7 +76,24 @@
SD_HandleTypeDef hsd; // create SDIO structure
#define TRANSFER_CLOCK_DIV (uint8_t(SDIO_INIT_CLK_DIV) / 40)
/*
SDIO_INIT_CLK_DIV is 118
SDIO clock frequency is 48MHz / (TRANSFER_CLOCK_DIV + 2)
SDIO init clock frequency should not exceed 400KHz = 48MHz / (118 + 2)
Default TRANSFER_CLOCK_DIV is 2 (118 / 40)
Default SDIO clock frequency is 48MHz / (2 + 2) = 12 MHz
This might be too fast for stable SDIO operations
MKS Robin board seems to have stable SDIO with BusWide 1bit and ClockDiv 8 i.e. 4.8MHz SDIO clock frequency
Additional testing is required as there are clearly some 4bit initialization problems
Add -DTRANSFER_CLOCK_DIV=8 to build parameters to improve SDIO stability
*/
#ifndef TRANSFER_CLOCK_DIV
#define TRANSFER_CLOCK_DIV (uint8_t(SDIO_INIT_CLK_DIV) / 40)
#endif
#ifndef USBD_OK
#define USBD_OK 0
@ -100,24 +117,25 @@
void SD_LowLevel_Init(void) {
uint32_t tempreg;
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_SDIO_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks
__HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = 1; //GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
#if DISABLED(STM32F1xx)
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
#endif
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // define D1-D3 only if have a four bit wide SDIO bus
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = 1; // GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
#endif
@ -125,10 +143,13 @@
GPIO_InitStruct.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk; // take SDIO out of reset
RCC->APB2ENR |= RCC_APB2RSTR_SDIORST_Msk; // enable SDIO clock
// Enable the DMA2 Clock
#if DISABLED(STM32F1xx)
// TODO: use __HAL_RCC_SDIO_RELEASE_RESET() and __HAL_RCC_SDIO_CLK_ENABLE();
RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk; // take SDIO out of reset
RCC->APB2ENR |= RCC_APB2RSTR_SDIORST_Msk; // enable SDIO clock
// Enable the DMA2 Clock
#endif
//Initialize the SDIO (with initial <400Khz Clock)
tempreg = 0; //Reset value
@ -156,10 +177,21 @@
bool status;
hsd.Instance = SDIO;
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
/*
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = 8;
*/
SD_LowLevel_Init();
uint8_t retry_Cnt = retryCnt;
for (;;) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
status = (bool) HAL_SD_Init(&hsd);
if (!status) break;
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
@ -170,6 +202,7 @@
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // go to 4 bit wide mode if pins are defined
retry_Cnt = retryCnt;
for (;;) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required
if (!--retry_Cnt) break;
}
@ -178,6 +211,7 @@
SD_LowLevel_Init();
retry_Cnt = retryCnt;
for (;;) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
status = (bool) HAL_SD_Init(&hsd);
if (!status) break;
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
@ -187,15 +221,15 @@
return true;
}
/*
void init_SDIO_pins(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
/**SDIO GPIO Configuration
PC8 ------> SDIO_D0
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
// SDIO GPIO Configuration
// PC8 ------> SDIO_D0
// PC12 ------> SDIO_CK
// PD2 ------> SDIO_CMD
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@ -217,7 +251,7 @@
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
*/
//bool SDIO_init() { return (bool) (SD_SDIO_Init() ? 1 : 0);}
//bool SDIO_Init_C() { return (bool) (SD_SDIO_Init() ? 1 : 0);}
@ -227,6 +261,7 @@
bool status;
for (;;) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
status = (bool) HAL_SD_ReadBlocks(&hsd, (uint8_t*)dst, block, 1, 1000); // read one 512 byte block with 500mS timeout
status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK
if (!status) break; // return passing status

10
Marlin/src/HAL/STM32/SoftwareSerial.cpp

@ -3,14 +3,14 @@
*
* Multi-instance software serial library for Arduino/Wiring
* -- Interrupt-driven receive and other improvements by ladyada
* (https://ladyada.net)
* <https://ladyada.net>
* -- Tuning, circular buffer, derivation from class Print/Stream,
* multi-instance support, porting to 8MHz processors,
* various optimizations, PROGMEM delay tables, inverse logic and
* direct port writing by Mikal Hart (http://www.arduiniana.org)
* -- Pin change interrupt macros by Paul Stoffregen (https://www.pjrc.com)
* -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
* -- ATmega1280/2560 support by Brett Hagman (https://www.roguerobotics.com/)
* direct port writing by Mikal Hart <http://www.arduiniana.org>
* -- Pin change interrupt macros by Paul Stoffregen <https://www.pjrc.com>
* -- 20MHz processor support by Garrett Mace <http://www.macetech.com>
* -- ATmega1280/2560 support by Brett Hagman <https://www.roguerobotics.com>
* -- STM32 support by Armin van der Togt
*
* This library is free software; you can redistribute it and/or

180
Marlin/src/HAL/STM32/tft/tft_fsmc.cpp

@ -0,0 +1,180 @@
/**
* 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 HAS_FSMC_TFT
#include "tft_fsmc.h"
#include "pinconfig.h"
SRAM_HandleTypeDef TFT_FSMC::SRAMx;
DMA_HandleTypeDef TFT_FSMC::DMAtx;
LCD_CONTROLLER_TypeDef *TFT_FSMC::LCD;
void TFT_FSMC::Init() {
uint32_t controllerAddress;
#if PIN_EXISTS(TFT_RESET)
OUT_WRITE(TFT_RESET_PIN, HIGH);
HAL_Delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
FSMC_NORSRAM_TimingTypeDef Timing, ExtTiming;
uint32_t NSBank = (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS);
SRAMx.Instance = FSMC_NORSRAM_DEVICE;
SRAMx.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
/* SRAMx.Init */
SRAMx.Init.NSBank = NSBank;
SRAMx.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
SRAMx.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
SRAMx.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
SRAMx.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
SRAMx.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
SRAMx.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
SRAMx.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
SRAMx.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
SRAMx.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
SRAMx.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE;
SRAMx.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
SRAMx.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
#ifdef STM32F4xx
SRAMx.Init.PageSize = FSMC_PAGE_SIZE_NONE;
#endif
/* Read Timing - relatively slow to ensure ID information is correctly read from TFT controller */
/* Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss */
Timing.AddressSetupTime = 15;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 24;
Timing.BusTurnAroundDuration = 0;
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FSMC_ACCESS_MODE_A;
/* Write Timing */
/* Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss */
ExtTiming.AddressSetupTime = 8;
ExtTiming.AddressHoldTime = 15;
ExtTiming.DataSetupTime = 8;
ExtTiming.BusTurnAroundDuration = 0;
ExtTiming.CLKDivision = 16;
ExtTiming.DataLatency = 17;
ExtTiming.AccessMode = FSMC_ACCESS_MODE_A;
__HAL_RCC_FSMC_CLK_ENABLE();
for(uint16_t i = 0; PinMap_FSMC[i].pin != NC; i++)
pinmap_pinout(PinMap_FSMC[i].pin, PinMap_FSMC);
pinmap_pinout(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS);
pinmap_pinout(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS);
controllerAddress = FSMC_BANK1_1;
#ifdef PF0
switch (NSBank) {
case FSMC_NORSRAM_BANK2: controllerAddress = FSMC_BANK1_2 ; break;
case FSMC_NORSRAM_BANK3: controllerAddress = FSMC_BANK1_3 ; break;
case FSMC_NORSRAM_BANK4: controllerAddress = FSMC_BANK1_4 ; break;
}
#endif
controllerAddress |= (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS);
HAL_SRAM_Init(&SRAMx, &Timing, &ExtTiming);
__HAL_RCC_DMA2_CLK_ENABLE();
#ifdef STM32F1xx
DMAtx.Instance = DMA2_Channel1;
#elif defined(STM32F4xx)
DMAtx.Instance = DMA2_Stream0;
DMAtx.Init.Channel = DMA_CHANNEL_0;
DMAtx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
DMAtx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
DMAtx.Init.MemBurst = DMA_MBURST_SINGLE;
DMAtx.Init.PeriphBurst = DMA_PBURST_SINGLE;
#endif
DMAtx.Init.Direction = DMA_MEMORY_TO_MEMORY;
DMAtx.Init.MemInc = DMA_MINC_DISABLE;
DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
DMAtx.Init.Mode = DMA_NORMAL;
DMAtx.Init.Priority = DMA_PRIORITY_HIGH;
LCD = (LCD_CONTROLLER_TypeDef *)controllerAddress;
}
uint32_t TFT_FSMC::GetID() {
uint32_t id;
WriteReg(0x0000);
id = LCD->RAM;
if (id == 0)
id = ReadID(LCD_READ_ID);
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = ReadID(LCD_READ_ID4);
return id;
}
uint32_t TFT_FSMC::ReadID(uint16_t Reg) {
uint32_t id;
WriteReg(Reg);
id = LCD->RAM; // dummy read
id = Reg << 24;
id |= (LCD->RAM & 0x00FF) << 16;
id |= (LCD->RAM & 0x00FF) << 8;
id |= LCD->RAM & 0x00FF;
return id;
}
bool TFT_FSMC::isBusy() {
if (__IS_DMA_ENABLED(&DMAtx))
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
Abort();
return __IS_DMA_ENABLED(&DMAtx);
}
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.PeriphInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
__HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx));
__HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx));
#ifdef STM32F1xx
DMAtx.Instance->CNDTR = Count;
DMAtx.Instance->CPAR = (uint32_t)Data;
DMAtx.Instance->CMAR = (uint32_t)&(LCD->RAM);
#elif defined(STM32F4xx)
DMAtx.Instance->NDTR = Count;
DMAtx.Instance->PAR = (uint32_t)Data;
DMAtx.Instance->M0AR = (uint32_t)&(LCD->RAM);
#endif
__HAL_DMA_ENABLE(&DMAtx);
}
#endif // HAS_FSMC_TFT

160
Marlin/src/HAL/STM32/tft/tft_fsmc.h

@ -0,0 +1,160 @@
/**
* 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 STM32F1xx
#include "stm32f1xx_hal.h"
#elif defined(STM32F4xx)
#include "stm32f4xx_hal.h"
#else
#error FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware.
#endif
#ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO TFT_FSMC
#ifdef STM32F1xx
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#elif defined(STM32F4xx)
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#endif
typedef struct {
__IO uint16_t REG;
__IO uint16_t RAM;
} LCD_CONTROLLER_TypeDef;
class TFT_FSMC {
private:
static SRAM_HandleTypeDef SRAMx;
static DMA_HandleTypeDef DMAtx;
static LCD_CONTROLLER_TypeDef *LCD;
static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data) { LCD->RAM = Data; __DSB(); }
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
static void Init();
static uint32_t GetID();
static bool isBusy();
static void Abort() { __HAL_DMA_DISABLE(&DMAtx); }
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) {}
static void DataTransferEnd() {};
static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { LCD->REG = Reg; __DSB(); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); }
};
#ifdef STM32F1xx
#define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)
#elif defined(STM32F4xx)
#define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FSMC)
#define FSMC_BANK1_1 0x60000000U
#define FSMC_BANK1_2 0x64000000U
#define FSMC_BANK1_3 0x68000000U
#define FSMC_BANK1_4 0x6C000000U
#else
#error No configuration for this MCU
#endif
const PinMap PinMap_FSMC[] = {
{PD_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D00
{PD_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D01
{PD_0, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D02
{PD_1, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D03
{PE_7, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D04
{PE_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D05
{PE_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D06
{PE_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D07
{PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08
{PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09
{PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10
{PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11
{PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12
{PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13
{PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14
{PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15
{PD_4, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NOE
{PD_5, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NWE
{NC, NP, 0}
};
const PinMap PinMap_FSMC_CS[] = {
{PD_7, (void *)FSMC_NORSRAM_BANK1, FSMC_PIN_DATA}, // FSMC_NE1
#ifdef PF0
{PG_9, (void *)FSMC_NORSRAM_BANK2, FSMC_PIN_DATA}, // FSMC_NE2
{PG_10, (void *)FSMC_NORSRAM_BANK3, FSMC_PIN_DATA}, // FSMC_NE3
{PG_12, (void *)FSMC_NORSRAM_BANK4, FSMC_PIN_DATA}, // FSMC_NE4
#endif
{NC, NP, 0}
};
#define FSMC_RS(A) (void *)((2 << A) - 2)
const PinMap PinMap_FSMC_RS[] = {
#ifdef PF0
{PF_0, FSMC_RS( 0), FSMC_PIN_DATA}, // FSMC_A0
{PF_1, FSMC_RS( 1), FSMC_PIN_DATA}, // FSMC_A1
{PF_2, FSMC_RS( 2), FSMC_PIN_DATA}, // FSMC_A2
{PF_3, FSMC_RS( 3), FSMC_PIN_DATA}, // FSMC_A3
{PF_4, FSMC_RS( 4), FSMC_PIN_DATA}, // FSMC_A4
{PF_5, FSMC_RS( 5), FSMC_PIN_DATA}, // FSMC_A5
{PF_12, FSMC_RS( 6), FSMC_PIN_DATA}, // FSMC_A6
{PF_13, FSMC_RS( 7), FSMC_PIN_DATA}, // FSMC_A7
{PF_14, FSMC_RS( 8), FSMC_PIN_DATA}, // FSMC_A8
{PF_15, FSMC_RS( 9), FSMC_PIN_DATA}, // FSMC_A9
{PG_0, FSMC_RS(10), FSMC_PIN_DATA}, // FSMC_A10
{PG_1, FSMC_RS(11), FSMC_PIN_DATA}, // FSMC_A11
{PG_2, FSMC_RS(12), FSMC_PIN_DATA}, // FSMC_A12
{PG_3, FSMC_RS(13), FSMC_PIN_DATA}, // FSMC_A13
{PG_4, FSMC_RS(14), FSMC_PIN_DATA}, // FSMC_A14
{PG_5, FSMC_RS(15), FSMC_PIN_DATA}, // FSMC_A15
#endif
{PD_11, FSMC_RS(16), FSMC_PIN_DATA}, // FSMC_A16
{PD_12, FSMC_RS(17), FSMC_PIN_DATA}, // FSMC_A17
{PD_13, FSMC_RS(18), FSMC_PIN_DATA}, // FSMC_A18
{PE_3, FSMC_RS(19), FSMC_PIN_DATA}, // FSMC_A19
{PE_4, FSMC_RS(20), FSMC_PIN_DATA}, // FSMC_A20
{PE_5, FSMC_RS(21), FSMC_PIN_DATA}, // FSMC_A21
{PE_6, FSMC_RS(22), FSMC_PIN_DATA}, // FSMC_A22
{PE_2, FSMC_RS(23), FSMC_PIN_DATA}, // FSMC_A23
#ifdef PF0
{PG_13, FSMC_RS(24), FSMC_PIN_DATA}, // FSMC_A24
{PG_14, FSMC_RS(25), FSMC_PIN_DATA}, // FSMC_A25
#endif
{NC, NP, 0}
};

212
Marlin/src/HAL/STM32/tft/tft_spi.cpp

@ -0,0 +1,212 @@
/**
* 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 HAS_SPI_TFT
#include "tft_spi.h"
#include "pinconfig.h"
SPI_HandleTypeDef TFT_SPI::SPIx;
DMA_HandleTypeDef TFT_SPI::DMAtx;
void TFT_SPI::Init() {
SPI_TypeDef *spiInstance;
#if PIN_EXISTS(TFT_RESET)
OUT_WRITE(TFT_RESET_PIN, HIGH);
HAL_Delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
OUT_WRITE(TFT_A0_PIN, HIGH);
OUT_WRITE(TFT_CS_PIN, HIGH);
if ((spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK)) == NP) return;
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI)) return;
#if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO)) return;
#endif
SPIx.Instance = spiInstance;
SPIx.State = HAL_SPI_STATE_RESET;
SPIx.Init.NSS = SPI_NSS_SOFT;
SPIx.Init.Mode = SPI_MODE_MASTER;
SPIx.Init.Direction =
#if TFT_MISO_PIN == TFT_MOSI_PIN
SPI_DIRECTION_1LINE;
#else
SPI_DIRECTION_2LINES;
#endif
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
SPIx.Init.CLKPhase = SPI_PHASE_1EDGE;
SPIx.Init.CLKPolarity = SPI_POLARITY_LOW;
SPIx.Init.DataSize = SPI_DATASIZE_8BIT;
SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPIx.Init.TIMode = SPI_TIMODE_DISABLE;
SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPIx.Init.CRCPolynomial = 10;
pinmap_pinout(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK);
pinmap_pinout(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI);
#if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
pinmap_pinout(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO);
#endif
pin_PullConfig(get_GPIO_Port(STM_PORT(digitalPinToPinName(TFT_SCK_PIN))), STM_LL_GPIO_PIN(digitalPinToPinName(TFT_SCK_PIN)), GPIO_PULLDOWN);
#ifdef SPI1_BASE
if (SPIx.Instance == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
DMAtx.Instance = DMA1_Channel3;
}
#endif
#ifdef SPI2_BASE
if (SPIx.Instance == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Channel5;
}
#endif
#ifdef SPI3_BASE
if (SPIx.Instance == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
DMAtx.Instance = DMA2_Channel2;
}
#endif
HAL_SPI_Init(&SPIx);
DMAtx.Init.Direction = DMA_MEMORY_TO_PERIPH;
DMAtx.Init.PeriphInc = DMA_PINC_DISABLE;
DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
DMAtx.Init.Mode = DMA_NORMAL;
DMAtx.Init.Priority = DMA_PRIORITY_LOW;
}
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.Init.DataSize = DataSize == DATASIZE_8BIT ? SPI_DATASIZE_8BIT : SPI_DATASIZE_16BIT;
HAL_SPI_Init(&SPIx);
WRITE(TFT_CS_PIN, LOW);
}
uint32_t TFT_SPI::GetID() {
uint32_t id;
id = ReadID(LCD_READ_ID);
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = ReadID(LCD_READ_ID4);
return id;
}
uint32_t TFT_SPI::ReadID(uint16_t Reg) {
#if !PIN_EXISTS(TFT_MISO)
return 0;
#else
uint32_t BaudRatePrescaler = SPIx.Init.BaudRatePrescaler;
uint32_t i, Data = 0;
SPIx.Init.BaudRatePrescaler = SPIx.Instance == SPI1 ? SPI_BAUDRATEPRESCALER_8 : SPI_BAUDRATEPRESCALER_4;
DataTransferBegin(DATASIZE_8BIT);
WriteReg(Reg);
if (SPIx.Init.Direction == SPI_DIRECTION_1LINE) SPI_1LINE_RX(&SPIx);
__HAL_SPI_ENABLE(&SPIx);
for (i = 0; i < 4; i++) {
#if TFT_MISO_PIN != TFT_MOSI_PIN
//if (hspi->Init.Direction == SPI_DIRECTION_2LINES) {
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
SPIx.Instance->DR = 0;
//}
#endif
while ((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
Data = (Data << 8) | SPIx.Instance->DR;
}
__HAL_SPI_DISABLE(&SPIx);
DataTransferEnd();
SPIx.Init.BaudRatePrescaler = BaudRatePrescaler;
return Data >> 7;
#endif
}
bool TFT_SPI::isBusy() {
if (DMAtx.Instance->CCR & DMA_CCR_EN)
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
Abort();
return DMAtx.Instance->CCR & DMA_CCR_EN;
}
void TFT_SPI::Abort() {
__HAL_DMA_DISABLE(&DMAtx);
DataTransferEnd();
}
void TFT_SPI::Transmit(uint16_t Data) {
#if TFT_MISO_PIN == TFT_MOSI_PIN
SPI_1LINE_TX(&SPIx);
#endif
__HAL_SPI_ENABLE(&SPIx);
SPIx.Instance->DR = Data;
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
#if TFT_MISO_PIN != TFT_MOSI_PIN
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); /* Clear overrun flag in 2 Lines communication mode because received is not read */
#endif
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.MemInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
DataTransferBegin();
#if TFT_MISO_PIN == TFT_MOSI_PIN
SPI_1LINE_TX(&SPIx);
#endif
DMAtx.DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << DMAtx.ChannelIndex);
DMAtx.Instance->CNDTR = Count;
DMAtx.Instance->CPAR = (uint32_t)&(SPIx.Instance->DR);
DMAtx.Instance->CMAR = (uint32_t)Data;
__HAL_DMA_ENABLE(&DMAtx);
__HAL_SPI_ENABLE(&SPIx);
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
}
#endif // HAS_SPI_TFT

67
Marlin/src/HAL/STM32/tft/tft_spi.h

@ -0,0 +1,67 @@
/**
* 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 STM32F1xx
#include "stm32f1xx_hal.h"
#elif defined(STM32F4xx)
#include "stm32f4xx_hal.h"
#else
#error SPI TFT is currently only supported on STM32F1 and STM32F4 hardware.
#endif
#ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO TFT_SPI
class TFT_SPI {
private:
static SPI_HandleTypeDef SPIx;
static DMA_HandleTypeDef DMAtx;
static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
static void Init();
static uint32_t GetID();
static bool isBusy();
static void Abort();
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT);
static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); };
static void DataTransferAbort();
static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
};

185
Marlin/src/HAL/STM32/tft/xpt2046.cpp

@ -0,0 +1,185 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 HAS_TFT_XPT2046
#include "xpt2046.h"
#include "pinconfig.h"
uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; }
SPI_HandleTypeDef XPT2046::SPIx;
DMA_HandleTypeDef XPT2046::DMAtx;
void XPT2046::Init() {
SPI_TypeDef *spiInstance;
OUT_WRITE(TOUCH_CS_PIN, HIGH);
#if PIN_EXISTS(TOUCH_INT)
// Optional Pendrive interrupt pin
SET_INPUT(TOUCH_INT_PIN);
#endif
spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK);
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI)) spiInstance = NP;
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO)) spiInstance = NP;
SPIx.Instance = spiInstance;
if (SPIx.Instance) {
SPIx.State = HAL_SPI_STATE_RESET;
SPIx.Init.NSS = SPI_NSS_SOFT;
SPIx.Init.Mode = SPI_MODE_MASTER;
SPIx.Init.Direction = SPI_DIRECTION_2LINES;
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
SPIx.Init.CLKPhase = SPI_PHASE_2EDGE;
SPIx.Init.CLKPolarity = SPI_POLARITY_HIGH;
SPIx.Init.DataSize = SPI_DATASIZE_8BIT;
SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPIx.Init.TIMode = SPI_TIMODE_DISABLE;
SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPIx.Init.CRCPolynomial = 10;
pinmap_pinout(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK);
pinmap_pinout(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI);
pinmap_pinout(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO);
#ifdef SPI1_BASE
if (SPIx.Instance == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
#ifdef STM32F1xx
DMAtx.Instance = DMA1_Channel3;
#elif defined(STM32F4xx)
DMAtx.Instance = DMA2_Stream3; // DMA2_Stream5
#endif
//SERIAL_ECHO_MSG(" Touch Screen on SPI1");
}
#endif
#ifdef SPI2_BASE
if (SPIx.Instance == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
#ifdef STM32F1xx
DMAtx.Instance = DMA1_Channel5;
#elif defined(STM32F4xx)
DMAtx.Instance = DMA1_Stream4;
#endif
//SERIAL_ECHO_MSG(" Touch Screen on SPI2");
}
#endif
#ifdef SPI3_BASE
if (SPIx.Instance == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
#ifdef STM32F1xx
DMAtx.Instance = DMA2_Channel2;
#elif defined(STM32F4xx)
DMAtx.Instance = DMA1_Stream5; // DMA1_Stream7
#endif
//SERIAL_ECHO_MSG(" Touch Screen on SPI3");
}
#endif
}
else {
SPIx.Instance = NULL;
SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN);
//SERIAL_ECHO_MSG(" Touch Screen on Software SPI");
}
getRawData(XPT2046_Z1);
}
bool XPT2046::isTouched() {
return isBusy() ? false : (
#if PIN_EXISTS(TOUCH_INT)
READ(TOUCH_INT_PIN) != HIGH
#else
getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD
#endif
);
}
bool XPT2046::getRawPoint(int16_t *x, int16_t *y) {
if (isBusy()) return false;
if (!isTouched()) return false;
*x = getRawData(XPT2046_X);
*y = getRawData(XPT2046_Y);
return isTouched();
}
uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) {
uint16_t data[3];
DataTransferBegin();
for (uint16_t i = 0; i < 3 ; i++) {
IO(coordinate);
data[i] = (IO() << 4) | (IO() >> 4);
}
DataTransferEnd();
uint16_t delta01 = delta(data[0], data[1]);
uint16_t delta02 = delta(data[0], data[2]);
uint16_t delta12 = delta(data[1], data[2]);
if (delta01 > delta02 || delta01 > delta12) {
if (delta02 > delta12)
data[0] = data[2];
else
data[1] = data[2];
}
return (data[0] + data[1]) >> 1;
}
uint16_t XPT2046::HardwareIO(uint16_t data) {
__HAL_SPI_ENABLE(&SPIx);
while((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
SPIx.Instance->DR = data;
while((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
__HAL_SPI_DISABLE(&SPIx);
return SPIx.Instance->DR;
}
uint16_t XPT2046::SoftwareIO(uint16_t data) {
uint16_t result = 0;
for (uint8_t j = 0x80; j > 0; j >>= 1) {
WRITE(TOUCH_SCK_PIN, LOW);
__DSB();
WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW);
__DSB();
if (READ(TOUCH_MISO_PIN)) result |= j;
__DSB();
WRITE(TOUCH_SCK_PIN, HIGH);
__DSB();
}
WRITE(TOUCH_SCK_PIN, LOW);
__DSB();
return result;
}
#endif // HAS_TFT_XPT2046

86
Marlin/src/HAL/STM32/tft/xpt2046.h

@ -0,0 +1,86 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 STM32F1xx
#include <stm32f1xx_hal.h>
#elif defined(STM32F4xx)
#include <stm32f4xx_hal.h>
#endif
#include "../../../inc/MarlinConfig.h"
// Not using regular SPI interface by default to avoid SPI mode conflicts with other SPI devices
#if !PIN_EXISTS(TOUCH_MISO)
#error "TOUCH_MISO_PIN is not defined."
#elif !PIN_EXISTS(TOUCH_MOSI)
#error "TOUCH_MOSI_PIN is not defined."
#elif !PIN_EXISTS(TOUCH_SCK)
#error "TOUCH_SCK_PIN is not defined."
#elif !PIN_EXISTS(TOUCH_CS)
#error "TOUCH_CS_PIN is not defined."
#endif
#ifndef TOUCH_INT_PIN
#define TOUCH_INT_PIN -1
#endif
#define XPT2046_DFR_MODE 0x00
#define XPT2046_SER_MODE 0x04
#define XPT2046_CONTROL 0x80
enum XPTCoordinate : uint8_t {
XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
};
#if !defined(XPT2046_Z1_THRESHOLD)
#define XPT2046_Z1_THRESHOLD 10
#endif
#ifdef STM32F1xx
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#elif defined(STM32F4xx)
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#endif
class XPT2046 {
private:
static SPI_HandleTypeDef SPIx;
static DMA_HandleTypeDef DMAtx;
static bool isBusy() { return SPIx.Instance ? __IS_DMA_ENABLED(&DMAtx) : false; }
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
static inline void DataTransferBegin() { if (SPIx.Instance) { HAL_SPI_Init(&SPIx); } WRITE(TOUCH_CS_PIN, LOW); };
static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
static uint16_t HardwareIO(uint16_t data);
static uint16_t SoftwareIO(uint16_t data);
static uint16_t IO(uint16_t data = 0) { return SPIx.Instance ? HardwareIO(data) : SoftwareIO(data); }
public:
static void Init();
static bool getRawPoint(int16_t *x, int16_t *y);
};

19
Marlin/src/HAL/STM32F1/HAL.h

@ -247,25 +247,6 @@ static int freeMemory() {
#pragma GCC diagnostic pop
//
// EEPROM
//
/**
* TODO: Write all this EEPROM stuff. Can emulate EEPROM in flash as last resort.
* Wire library should work for i2c EEPROMs.
*/
#if ANY(I2C_EEPROM_AT24C16, SPI_EEPROM_W25Q)
void eeprom_init(void);
void eeprom_hw_deinit(void);
#endif
uint8_t eeprom_read_byte(uint8_t *pos);
void eeprom_write_byte(uint8_t *pos, unsigned char value);
void eeprom_read_block(void *__dst, const void *__src, size_t __n);
void eeprom_update_block(const void *__src, void *__dst, size_t __n);
//
// ADC
//

2
Marlin/src/HAL/STM32F1/SPI.cpp

@ -277,7 +277,7 @@ void SPIClass::read(uint8_t *buf, uint32_t len) {
regs->DR = 0x00FF; // write the first byte
// main loop
while (--len) {
while(!(regs->SR & SPI_SR_TXE)) { /* nada */ } // wait for TXE flag
while (!(regs->SR & SPI_SR_TXE)) { /* nada */ } // wait for TXE flag
noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data
regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag.
while (!(regs->SR & SPI_SR_RXNE)) { /* nada */ } // wait till data is available in the DR register

2
Marlin/src/HAL/STM32F1/SPI.h

@ -208,6 +208,8 @@ public:
*/
void setDataSize(uint32_t ds);
uint32_t getDataSize() { return _currentSetting->dataSize; }
/* Victor Perez 2017. Added to set and clear callback functions for callback
* on DMA transfer completion.
* onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed

198
Marlin/src/HAL/STM32F1/eeprom_i2c_at24.cpp

@ -1,198 +0,0 @@
/**
AT24C16, 16K SERIAL EEPROM:
Internally organized with 128 pages of 16 bytes each (2048 bytes)
16K requires an 11-bit data word address for random word addressing.
The 16K does not use any device address bits but instead the 3 bits are used for mem-
ory page addressing. These page addressing bits on the 4K, 8K and 16K devices
should be considered the most significant bits of the data word address which follows.
The A0, A1 and A2 pins are no connect.
*/
#include "../../inc/MarlinConfig.h"
#if ENABLED(I2C_EEPROM_AT24C16)
#include "../HAL.h"
#include "../../module/mks_wifi/small_cmsis.h"
#include "../../module/mks_wifi/dwt.h"
#define DEV_ADDR 0xA0
#define FSMC_DISABLE RCC->AHBENR &= ~RCC_AHBENR_FSMCEN //Конфликт на ноге FSMC_NADV с I2C. На время передачи приходится отключать FSMC
#define FSMC_RESTORE RCC->AHBENR |= RCC_AHBENR_FSMCEN;
#define I2C_TIMEOUT 2000 //таймаут на ожидание опереций I2C.
#define CHECK_TIMEOUT do{if(dwt_get_timeout() == 0){ERROR("Timeout");return 0;}}while(0)
static bool waitSRBitSet(uint32_t Bit);
static uint8_t i2c_write(const uint8_t hw_adr, uint8_t *data, uint32_t len);
static uint8_t i2c_read(const uint8_t hw_adr, uint16_t addr, uint8_t *data, uint32_t len);
void eeprom_hw_deinit(void){
DEBUG("Finish I2C");
}
void eeprom_init(void){
/*
PB6 SCL Alternate function open drain
PB7 SDA Alternate function open drain
*/
DEBUG("Init I2C");
dwt_init();
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN|RCC_APB2ENR_AFIOEN;
PORTB->CRL |= (GPIO_CRL_MODE6|GPIO_CRL_MODE7|GPIO_CRL_CNF6|GPIO_CRL_CNF7);
AFIO->MAPR2 |= AFIO_MAPR2_FSMC_NADV_REMAP; //Remap по факту не работает, бит не устанавливается.
RCC->APB1ENR|= RCC_APB1ENR_I2C1EN;
I2C1->CR1 = I2C_CR1_SWRST;
I2C1->CR1 = 0;
//Тактовая 72Mhz, PCLK 36Mhz
I2C1->CCR = (180 << I2C_CCR_CCR_Pos);
I2C1->CR2 = (36 << I2C_CR2_FREQ_Pos);
I2C1->TRISE = 37;
I2C1->CR1 = I2C_CR1_PE;
}
void eeprom_write_byte(uint8_t *pos, unsigned char value){
uint8_t data[2];
FSMC_DISABLE;
data[0]=(uint8_t)((unsigned)pos % 256);
data[1]=(uint8_t)(value);
if(!i2c_write((DEV_ADDR+(uint8_t)(((unsigned)pos/256)<<1)),data,2)){
ERROR("write failed");
}
safe_delay(20); //Задержка на время пока eeprom пишет.
FSMC_RESTORE;
}
uint8_t eeprom_read_byte(uint8_t *pos) {
uint8_t data;
FSMC_DISABLE;
if(!i2c_read(DEV_ADDR, (uint16_t)((unsigned)pos), &data, 1)){
ERROR("read failed");
data=0;
}
safe_delay(1); //небольшая пауза перед включением FSMC, чтобы состояние STOP успело выставиться на линии.
FSMC_RESTORE;
return data;
}
void eeprom_read_block(void *__dst, const void *__src, size_t __n){
ERROR("Call to missing function");
};
void eeprom_update_block(const void *__src, void *__dst, size_t __n){
ERROR("Call to missing function");
};
static uint8_t i2c_write(const uint8_t hw_adr, uint8_t *data, uint32_t len){
//DEBUG("i2c write at %d val %0X",data[0],data[1]);
dwt_settimeout(I2C_TIMEOUT);
//DEBUG("Wait busy");
while(I2C1->SR2 & I2C_SR2_BUSY) {CHECK_TIMEOUT;};
I2C1->CR1 = I2C_CR1_PE | I2C_CR1_START;
dwt_settimeout(I2C_TIMEOUT);
//DEBUG("Wait SB");
while(!(I2C1->SR1 & I2C_SR1_SB)) {CHECK_TIMEOUT;};
I2C1->DR = (hw_adr & 0xFE);
if(!waitSRBitSet(I2C_SR1_ADDR)) return false;
(void)I2C1->SR2;
while(len--){
if(!waitSRBitSet(I2C_SR1_TXE)) return false;
I2C1->DR = *data++;
}
dwt_settimeout(I2C_TIMEOUT);
//DEBUG("Wait BTF");
while(!((I2C1->SR1 & I2C_SR1_TXE) && (I2C1->SR1 & I2C_SR1_BTF))) {CHECK_TIMEOUT;};
I2C1->CR1 = I2C_CR1_PE | I2C_CR1_STOP;
return 1;
}
static uint8_t i2c_read(const uint8_t hw_adr, uint16_t addr, uint8_t *data, uint32_t len){
dwt_settimeout(I2C_TIMEOUT);
//DEBUG("Wait busy");
while(I2C1->SR2 & I2C_SR2_BUSY) {CHECK_TIMEOUT;};
//Запись адреса
I2C1->CR1 = I2C_CR1_PE | I2C_CR1_START;
dwt_settimeout(I2C_TIMEOUT);
//DEBUG("Wait SB");
while(!(I2C1->SR1 & I2C_SR1_SB)) {CHECK_TIMEOUT;}; //Условие старт
I2C1->DR = ((hw_adr & 0xFE) + ((addr/256) << 1));
if(!waitSRBitSet(I2C_SR1_ADDR)) return false; //i2c адрес отправлен
I2C1->SR2;
if(!waitSRBitSet(I2C_SR1_TXE)) return false;
I2C1->DR = addr%256; //адрес в памяти отправлен
dwt_settimeout(I2C_TIMEOUT);
//DEBUG("Wait BTF");
while(!((I2C1->SR1 & I2C_SR1_TXE) && (I2C1->SR1 & I2C_SR1_BTF))) {CHECK_TIMEOUT;};
//Чтение
I2C1->CR1 = I2C_CR1_PE | I2C_CR1_START | I2C_CR1_ACK;
dwt_settimeout(I2C_TIMEOUT);
//DEBUG("Wait SB");
while(!(I2C1->SR1 & I2C_SR1_SB)) {CHECK_TIMEOUT;};
I2C1->DR = hw_adr|1;
if(!waitSRBitSet(I2C_SR1_ADDR)) return false;
I2C1->SR2;
I2C1->CR1 = I2C_CR1_PE | I2C_CR1_STOP;
if(!waitSRBitSet(I2C_SR1_RXNE)) return false;
*data = I2C1->DR;
return true;
}
static bool waitSRBitSet(uint32_t Bit){
uint32_t sr;
dwt_settimeout(I2C_TIMEOUT);
do{
sr = I2C1->SR1;
if(sr & ( I2C_SR1_AF | I2C_SR1_ARLO | I2C_SR1_BERR)){
I2C1->CR1 = I2C_CR1_PE | I2C_CR1_STOP;
I2C1->SR1 = 0;
ERROR("I2C Error flag %0X",sr);
return false;
}
if(dwt_get_timeout() == 0){
ERROR("Timeout %0X",Bit);
return false;
}
}while(!(sr & Bit));
return true;
};
#endif // I2C_EEPROM

2
Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp

@ -39,7 +39,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
#define _ALIGN(x) __attribute__ ((aligned(x))) // SDIO uint32_t* compat.
static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE];

23
Marlin/src/HAL/STM32F1/eeprom_spi_w25q.cpp

@ -7,40 +7,43 @@ U5 W25Q64BV, 16K SERIAL EEPROM:
#include "../../inc/MarlinConfig.h"
#if ENABLED(SPI_EEPROM_W25Q)
#include "../../libs/W25Qxx.h"
W25QXXFlash W25QXX;
uint8_t spi_eeprom[MARLIN_EEPROM_SIZE];
#include "w25q64.h"
void eeprom_init(void){
DEBUG("Start EEPROM");
w25q_init();
w25q_read(SPI_EEPROM_OFFSET,(uint8_t *)spi_eeprom,SPI_EEPROM_SIZE);
W25QXX.init(SPI_QUARTER_SPEED);
W25QXX.SPI_FLASH_BufferRead((uint8_t *)spi_eeprom,SPI_EEPROM_OFFSET,MARLIN_EEPROM_SIZE);
}
void eeprom_hw_deinit(void){
DEBUG("Finish EEPROM");
w25q_write_enable();
w25q_sector_erase(SPI_EEPROM_OFFSET);
W25QXX.SPI_FLASH_WriteEnable();
W25QXX.SPI_FLASH_SectorErase(SPI_EEPROM_OFFSET);
//write
w25q_write(SPI_EEPROM_OFFSET,(uint8_t *)spi_eeprom,SPI_EEPROM_SIZE);
W25QXX.SPI_FLASH_BufferWrite((uint8_t *)spi_eeprom,SPI_EEPROM_OFFSET,MARLIN_EEPROM_SIZE);
}
void eeprom_write_byte(uint8_t *pos, unsigned char value){
uint16_t addr=(unsigned)pos;
if(addr < SPI_EEPROM_SIZE){
if(addr < MARLIN_EEPROM_SIZE){
spi_eeprom[addr]=value;
}else{
ERROR("Write out of SPI size: %d %d",addr,SPI_EEPROM_SIZE);
ERROR("Write out of SPI size: %d %d",addr,MARLIN_EEPROM_SIZE);
}
}
uint8_t eeprom_read_byte(uint8_t *pos) {
uint16_t addr=(unsigned)pos;
if(addr < SPI_EEPROM_SIZE){
if(addr < MARLIN_EEPROM_SIZE){
return spi_eeprom[addr];
}else{
ERROR("Read out of SPI size: %d %d",addr,SPI_EEPROM_SIZE);
ERROR("Read out of SPI size: %d %d",addr,MARLIN_EEPROM_SIZE);
return 0;
}
}

16
Marlin/src/HAL/STM32F1/eeprom_wired.cpp

@ -36,9 +36,15 @@
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
bool PersistentStore::access_finish() {
#if ENABLED(EEPROM_W25Q)
eeprom_hw_deinit();
#endif
return true;
}
bool PersistentStore::access_start() {
eeprom_init();
#ifndef SPI_EEPROM_W25Q
#if ENABLED(SPI_EEPROM)
#if SPI_CHAN_EEPROM1 == 1
SET_OUTPUT(BOARD_SPI1_SCK_PIN);
@ -48,16 +54,8 @@ bool PersistentStore::access_start() {
#endif
spiInit(0);
#endif
#endif
return true;
}
bool PersistentStore::access_finish() {
#if ANY(I2C_EEPROM_AT24C16, SPI_EEPROM_W25Q)
eeprom_hw_deinit();
#endif
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {

7
Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h

@ -25,3 +25,10 @@
//#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE."
#undef SD_CHECK_AND_RETRY
#endif
// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
#undef TOUCH_SCREEN
#undef TOUCH_SCREEN_CALIBRATION
#define HAS_TOUCH_XPT2046 1
#endif

4
Marlin/src/HAL/STM32F1/inc/SanityCheck.h

@ -51,3 +51,7 @@
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#endif
#if ENABLED(NEOPIXEL_LED)
#error "NEOPIXEL_LED (Adafruit NeoPixel) is not supported for HAL/STM32F1. Comment out this line to proceed at your own risk!"
#endif

6
Marlin/src/HAL/STM32F1/onboard_sd.cpp

@ -11,9 +11,11 @@
* Redistributions of source code must retain the above copyright notice.
*
*/
#if 0
#include "../../inc/MarlinConfig.h"
#ifndef MKS_WIFI
#if SD_CONNECTION_IS(ONBOARD)
#include "onboard_sd.h"
@ -554,4 +556,4 @@ DRESULT disk_read (
#endif // _DISKIO_IOCTL
#endif // SD_CONNECTION_IS(ONBOARD)
#endif
#endif

5
Marlin/src/HAL/STM32F1/onboard_sd.h

@ -3,9 +3,11 @@
/ * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech]
/ * Low level disk interface module include file (C)ChaN, 2015
/-----------------------------------------------------------------------*/
#if 0
#pragma once
#ifndef MKS_WIFI
#define _DISKIO_WRITE 1 /* 1: Enable disk_write function */
#define _DISKIO_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
#define _DISKIO_ISDIO 0 /* 1: Enable iSDIO control fucntion */
@ -94,4 +96,5 @@ DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
#define CT_SD2 0x04 /* SD ver 2 */
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
#define CT_BLOCK 0x08 /* Block addressing */
#endif

51
Marlin/src/HAL/STM32F1/small_spi.cpp

@ -1,51 +0,0 @@
#include "small_spi.h"
#include "../../inc/MarlinConfig.h"
/*
SPI2
MISO - PB14 Input floating / Input pull-up
MOSI - PB15 Alternate function push-pull
SCK - PB13 Alternate function push-pull
W25Q CS - PB12 Out push-pull
TOUCH CS - PA7
*/
void spi2_init(uint8_t prescaler){
uint32_t tmp;
if(prescaler > SPI_FREQ_140Khz){
prescaler = SPI_FREQ_140Khz;
}
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN|RCC_APB2ENR_IOPAEN|RCC_APB2ENR_AFIOEN;
tmp = PORTB->CRH;
tmp &= ~(GPIO_CRH_MODE14|GPIO_CRH_CNF14|GPIO_CRH_CNF12|GPIO_CRH_CNF13|GPIO_CRH_CNF14|GPIO_CRH_CNF15);
tmp |= (GPIO_CRH_MODE12|GPIO_CRH_MODE13|GPIO_CRH_MODE15|GPIO_CRH_CNF13_1|GPIO_CRH_CNF15_1|GPIO_CRH_CNF14_0);
PORTB->CRH = tmp;
//CS PIN
tmp= PORTA->CRL;
tmp &= ~GPIO_CRL_CNF7;
tmp |= GPIO_CRL_MODE7;
PORTA->CRL = tmp;
SPI2_STOP_ALL;
RCC->APB1ENR|= RCC_APB1ENR_SPI2EN;
SPI2->CR1 = SPI_CR1_SSM|\
SPI_CR1_SSI|\
(prescaler << SPI_CR1_BR_Pos)|\
SPI_CR1_MSTR;
SPI2->CR1 |= SPI_CR1_SPE;
}
uint8_t spi_send(uint8_t data){
while((SPI2->SR & SPI_SR_TXE) == 0){NOP;};
SPI2->DR = data;
while((SPI2->SR & SPI_SR_RXNE) == 0){NOP;};
return SPI2->DR;
}

34
Marlin/src/HAL/STM32F1/small_spi.h

@ -1,34 +0,0 @@
#ifndef SMALL_SPI_H
#define SMALL_SPI_H
#include "../HAL.h"
#include "../../module/mks_wifi/small_cmsis.h"
#define SPI_FREQ_18Mhz (uint8_t)0
#define SPI_FREQ_9Mhz (uint8_t)1
#define SPI_FREQ_4_5Mhz (uint8_t)2
#define SPI_FREQ_2_25Mhz (uint8_t)3
#define SPI_FREQ_1_125Mhz (uint8_t)4
#define SPI_FREQ_560KHz (uint8_t)5
#define SPI_FREQ_280KHz (uint8_t)6
#define SPI_FREQ_140Khz (uint8_t)7
#define SPI_DIR_READ 0
#define SPI_DIR_WRITE 1
#define W25Q_START do{PORTB->BSRR=GPIO_BSRR_BR12;PORTA->BSRR=GPIO_BSRR_BS7;}while(0)
#define W25Q_STOP PORTB->BSRR=GPIO_BSRR_BS12
#define TOUCH_CS_START do{PORTB->BSRR=GPIO_BSRR_BS12;PORTA->BSRR=GPIO_BSRR_BR7;}while(0)
#define TOUCH_CS_STOP PORTA->BSRR=GPIO_BSRR_BS7
#define SPI2_STOP_ALL do{PORTB->BSRR=GPIO_BSRR_BS12;PORTA->BSRR=GPIO_BSRR_BS7;}while(0)
uint8_t spi_send(uint8_t data);
void spi_read(uint32_t addr, uint8_t *buf, uint32_t len);
void spi_write(uint32_t addr, uint8_t *buf, uint32_t len);
void spi2_init(uint8_t prescaler);
#endif

211
Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp → Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp

@ -20,96 +20,16 @@
*
*/
/**
* u8g_com_stm32duino_fsmc.cpp
*
* Communication interface for FSMC
*/
#include "../../../inc/MarlinConfig.h"
#if defined(ARDUINO_ARCH_STM32F1) && PIN_EXISTS(FSMC_CS) // FSMC on 100/144 pins SoCs
#if HAS_GRAPHICAL_LCD
#if HAS_FSMC_TFT
#include <U8glib.h>
#include "tft_fsmc.h"
#include <libmaple/fsmc.h>
#include <libmaple/gpio.h>
#include <libmaple/dma.h>
#include <boards.h>
#ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
/* Timing configuration */
#define FSMC_ADDRESS_SETUP_TIME 15 // AddressSetupTime
#define FSMC_DATA_SETUP_TIME 15 // DataSetupTime
void LCD_IO_Init(uint8_t cs, uint8_t rs);
void LCD_IO_WriteData(uint16_t RegValue);
void LCD_IO_WriteReg(uint16_t Reg);
uint16_t LCD_IO_ReadData(uint16_t RegValue);
uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize);
#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
static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT
uint8_t u8g_com_stm32duino_fsmc_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
if (msgInitCount) {
if (msg == U8G_COM_MSG_INIT) msgInitCount--;
if (msgInitCount) return -1;
}
static uint8_t isCommand;
switch (msg) {
case U8G_COM_MSG_STOP: break;
case U8G_COM_MSG_INIT:
u8g_SetPIOutput(u8g, U8G_PI_RESET);
#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(u8g->pin_list[U8G_PI_CS], u8g->pin_list[U8G_PI_A0]);
u8g_Delay(50);
if (arg_ptr) {
*((uint32_t *)arg_ptr) = LCD_IO_ReadData(0x0000);
if (*((uint32_t *)arg_ptr) == 0)
*((uint32_t *)arg_ptr) = (LCD_READ_ID << 24) | LCD_IO_ReadData(LCD_READ_ID, 3);
}
isCommand = 0;
break;
case U8G_COM_MSG_ADDRESS: // define cmd (arg_val = 0) or data mode (arg_val = 1)
isCommand = arg_val == 0 ? 1 : 0;
break;
case U8G_COM_MSG_RESET:
u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
break;
case U8G_COM_MSG_WRITE_BYTE:
if (isCommand)
LCD_IO_WriteReg(arg_val);
else
LCD_IO_WriteData((uint16_t)arg_val);
break;
case U8G_COM_MSG_WRITE_SEQ:
for (uint8_t i = 0; i < arg_val; i += 2)
LCD_IO_WriteData(*(uint16_t *)(((uint32_t)arg_ptr) + i));
break;
}
return 1;
}
LCD_CONTROLLER_TypeDef *TFT_FSMC::LCD;
/**
* FSMC LCD IO
@ -160,27 +80,35 @@ __attribute__((always_inline)) __STATIC_INLINE void __DSB() {
#define FSMC_RS_A25 PG14
#endif
/* Timing configuration */
#define FSMC_ADDRESS_SETUP_TIME 15 // AddressSetupTime
#define FSMC_DATA_SETUP_TIME 15 // DataSetupTime
static uint8_t fsmcInit = 0;
void TFT_FSMC::Init() {
uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN;
uint32_t controllerAddress;
typedef struct {
__IO uint16_t REG;
__IO uint16_t RAM;
} LCD_CONTROLLER_TypeDef;
#if PIN_EXISTS(TFT_RESET)
OUT_WRITE(TFT_RESET_PIN, HIGH);
delay(100);
#endif
LCD_CONTROLLER_TypeDef *LCD;
#if PIN_EXISTS(TFT_BACKLIGHT)
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
void LCD_IO_Init(uint8_t cs, uint8_t rs) {
uint32_t controllerAddress;
struct fsmc_nor_psram_reg_map* fsmcPsramRegion;
if (fsmcInit) return;
fsmcInit = 1;
switch (cs) {
case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; break;
case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; fsmcPsramRegion = FSMC_NOR_PSRAM1_BASE; break;
#if ENABLED(STM32_XL_DENSITY)
case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; break;
case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; break;
case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; break;
case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; fsmcPsramRegion = FSMC_NOR_PSRAM2_BASE; break;
case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; fsmcPsramRegion = FSMC_NOR_PSRAM3_BASE; break;
case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; fsmcPsramRegion = FSMC_NOR_PSRAM4_BASE; break;
#endif
default: return;
}
@ -246,90 +174,65 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) {
gpio_set_mode(PIN_MAP[cs].gpio_device, PIN_MAP[cs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_CS_NEx
gpio_set_mode(PIN_MAP[rs].gpio_device, PIN_MAP[rs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_RS_Ax
#if ENABLED(STM32_XL_DENSITY)
FSMC_NOR_PSRAM4_BASE->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN;
FSMC_NOR_PSRAM4_BASE->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME;
#else // PSRAM1 for STM32F103V (high density)
FSMC_NOR_PSRAM1_BASE->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN;
FSMC_NOR_PSRAM1_BASE->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME;
#endif
fsmcPsramRegion->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN;
fsmcPsramRegion->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME;
afio_remap(AFIO_REMAP_FSMC_NADV);
LCD = (LCD_CONTROLLER_TypeDef*)controllerAddress;
}
void LCD_IO_WriteData(uint16_t RegValue) {
LCD->RAM = RegValue;
void TFT_FSMC::Transmit(uint16_t Data) {
LCD->RAM = Data;
__DSB();
}
void LCD_IO_WriteReg(uint16_t Reg) {
void TFT_FSMC::WriteReg(uint16_t Reg) {
LCD->REG = Reg;
__DSB();
}
uint16_t LCD_IO_ReadData(uint16_t RegValue) {
LCD->REG = RegValue;
__DSB();
uint32_t TFT_FSMC::GetID() {
uint32_t id;
WriteReg(0x0000);
id = LCD->RAM;
return LCD->RAM;
if (id == 0)
id = ReadID(LCD_READ_ID);
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = ReadID(LCD_READ_ID4);
return id;
}
uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) {
volatile uint32_t data;
LCD->REG = RegValue;
__DSB();
uint32_t TFT_FSMC::ReadID(uint16_t Reg) {
uint32_t id;
WriteReg(Reg);
id = LCD->RAM; // dummy read
id = Reg << 24;
id |= (LCD->RAM & 0x00FF) << 16;
id |= (LCD->RAM & 0x00FF) << 8;
id |= LCD->RAM & 0x00FF;
return id;
}
bool TFT_FSMC::isBusy() {
return false;
}
data = LCD->RAM; // dummy read
data = LCD->RAM & 0x00FF;
void TFT_FSMC::Abort() {
while (--ReadSize) {
data <<= 8;
data |= (LCD->RAM & 0x00FF);
}
return uint32_t(data);
}
#ifdef LCD_USE_DMA_FSMC
void LCD_IO_WriteMultiple(uint16_t color, uint32_t count) {
while (count > 0) {
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, &color, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM);
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, count > 65535 ? 65535 : count);
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
#if defined(FSMC_DMA_DEV) && defined(FSMC_DMA_CHANNEL)
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | MemoryIncrease);
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Count);
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {};
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
count = count > 65535 ? count - 65535 : 0;
}
}
void LCD_IO_WriteSequence(uint16_t *data, uint16_t length) {
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | DMA_PINC_MODE);
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, length);
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {};
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
}
void LCD_IO_WriteSequence_Async(uint16_t *data, uint16_t length) {
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | DMA_PINC_MODE);
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, length);
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
}
void LCD_IO_WaitSequence_Async() {
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {};
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
#endif
}
#endif // LCD_USE_DMA_FSMC
#endif // HAS_GRAPHICAL_LCD
#endif // ARDUINO_ARCH_STM32F1 && FSMC_CS_PIN
#endif // HAS_FSMC_TFT

71
Marlin/src/HAL/STM32F1/tft/tft_fsmc.h

@ -0,0 +1,71 @@
/**
* 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
#ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#include <libmaple/dma.h>
#define DATASIZE_8BIT DMA_SIZE_8BITS
#define DATASIZE_16BIT DMA_SIZE_16BITS
#define TFT_IO TFT_FSMC
typedef struct {
__IO uint16_t REG;
__IO uint16_t RAM;
} LCD_CONTROLLER_TypeDef;
class TFT_FSMC {
private:
static LCD_CONTROLLER_TypeDef *LCD;
static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
static void Init();
static uint32_t GetID();
static bool isBusy();
static void Abort();
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) {};
static void DataTransferEnd() {};
static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg);
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_MODE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_CIRC_MODE, &Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_CIRC_MODE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
}
}
};

149
Marlin/src/HAL/STM32F1/tft/tft_spi.cpp

@ -0,0 +1,149 @@
/**
* 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 HAS_SPI_TFT
#include "tft_spi.h"
// TFT_SPI tft;
SPIClass TFT_SPI::SPIx(1);
#define TFT_CS_H OUT_WRITE(TFT_CS_PIN, HIGH)
#define TFT_CS_L OUT_WRITE(TFT_CS_PIN, LOW)
#define TFT_DC_H OUT_WRITE(TFT_DC_PIN, HIGH)
#define TFT_DC_L OUT_WRITE(TFT_DC_PIN, LOW)
#define TFT_RST_H OUT_WRITE(TFT_RST_PIN, HIGH)
#define TFT_RST_L OUT_WRITE(TFT_RST_PIN, LOW)
#define TFT_BLK_H OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH)
#define TFT_BLK_L OUT_WRITE(TFT_BACKLIGHT_PIN, LOW)
void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET)
// OUT_WRITE(TFT_RESET_PIN, HIGH);
TFT_RST_H;
delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
// OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
TFT_BLK_H;
#endif
TFT_DC_H;
TFT_CS_H;
/**
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/
#if SPI_DEVICE == 1
#define SPI_CLOCK_MAX SPI_CLOCK_DIV4
#else
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
#endif
uint8_t clock;
uint8_t spiRate = SPI_FULL_SPEED;
switch (spiRate) {
case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break;
case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break;
case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break;
case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
}
SPIx.setModule(1);
SPIx.setClockDivider(clock);
SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0);
}
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.setDataSize(DataSize);
SPIx.begin();
TFT_CS_L;
}
uint32_t TFT_SPI::GetID() {
uint32_t id;
id = ReadID(LCD_READ_ID);
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = ReadID(LCD_READ_ID4);
return id;
}
uint32_t TFT_SPI::ReadID(uint16_t Reg) {
#if !PIN_EXISTS(TFT_MISO)
return 0;
#else
uint8_t d = 0;
uint32_t data = 0;
SPIx.setClockDivider(SPI_CLOCK_DIV16);
DataTransferBegin(DATASIZE_8BIT);
WriteReg(Reg);
LOOP_L_N(i, 4) {
SPIx.read((uint8_t*)&d, 1);
data = (data << 8) | d;
}
DataTransferEnd();
SPIx.setClockDivider(SPI_CLOCK_MAX);
return data >> 7;
#endif
}
bool TFT_SPI::isBusy() {
return false;
}
void TFT_SPI::Abort() {
DataTransferEnd();
}
void TFT_SPI::Transmit(uint16_t Data) {
SPIx.send(Data);
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DataTransferBegin();
TFT_DC_H;
if (MemoryIncrease == DMA_MINC_ENABLE) {
SPIx.dmaSend(Data, Count, true);
}
else {
SPIx.dmaSend(Data, Count, false);
}
DataTransferEnd();
}
#endif // HAS_SPI_TFT

72
Marlin/src/HAL/STM32F1/tft/tft_spi.h

@ -0,0 +1,72 @@
/**
* 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"
#include <SPI.h>
#ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT DATA_SIZE_8BIT
#define DATASIZE_16BIT DATA_SIZE_16BIT
#define TFT_IO TFT_SPI
#define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0
class TFT_SPI {
private:
static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
static SPIClass SPIx;
static void Init();
static uint32_t GetID();
static bool isBusy();
static void Abort();
static void DataTransferBegin(uint16_t DataWidth = DATA_SIZE_16BIT);
static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); SPIx.end(); };
static void DataTransferAbort();
static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
}
}
};

141
Marlin/src/HAL/STM32F1/tft/xpt2046.cpp

@ -0,0 +1,141 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046
#include "xpt2046.h"
#include <SPI.h>
uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; }
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
#include <SPI.h>
SPIClass XPT2046::SPIx(TOUCH_BUTTONS_HW_SPI_DEVICE);
static void touch_spi_init(uint8_t spiRate) {
/**
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/
uint8_t clock;
switch (spiRate) {
case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV4; break;
case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break;
case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break;
case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
}
XPT2046::SPIx.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE);
XPT2046::SPIx.setClockDivider(clock);
XPT2046::SPIx.setBitOrder(MSBFIRST);
XPT2046::SPIx.setDataMode(SPI_MODE0);
}
#endif // TOUCH_BUTTONS_HW_SPI
void XPT2046::Init() {
SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN);
OUT_WRITE(TOUCH_CS_PIN, HIGH);
#if PIN_EXISTS(TOUCH_INT)
// Optional Pendrive interrupt pin
SET_INPUT(TOUCH_INT_PIN);
#endif
TERN_(TOUCH_BUTTONS_HW_SPI, touch_spi_init(SPI_SPEED_6));
// Read once to enable pendrive status pin
getRawData(XPT2046_X);
}
bool XPT2046::isTouched() {
return isBusy() ? false : (
#if PIN_EXISTS(TOUCH_INT)
READ(TOUCH_INT_PIN) != HIGH
#else
getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD
#endif
);
}
bool XPT2046::getRawPoint(int16_t *x, int16_t *y) {
if (isBusy()) return false;
if (!isTouched()) return false;
*x = getRawData(XPT2046_X);
*y = getRawData(XPT2046_Y);
return isTouched();
}
uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) {
uint16_t data[3];
DataTransferBegin();
TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.begin());
for (uint16_t i = 0; i < 3 ; i++) {
IO(coordinate);
data[i] = (IO() << 4) | (IO() >> 4);
}
TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.end());
DataTransferEnd();
uint16_t delta01 = delta(data[0], data[1]),
delta02 = delta(data[0], data[2]),
delta12 = delta(data[1], data[2]);
if (delta01 > delta02 || delta01 > delta12)
data[delta02 > delta12 ? 0 : 1] = data[2];
return (data[0] + data[1]) >> 1;
}
uint16_t XPT2046::IO(uint16_t data) {
return TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data);
}
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
uint16_t XPT2046::HardwareIO(uint16_t data) {
uint16_t result = SPIx.transfer(data);
return result;
}
#endif
uint16_t XPT2046::SoftwareIO(uint16_t data) {
uint16_t result = 0;
for (uint8_t j = 0x80; j; j >>= 1) {
WRITE(TOUCH_SCK_PIN, LOW);
WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW);
if (READ(TOUCH_MISO_PIN)) result |= j;
WRITE(TOUCH_SCK_PIN, HIGH);
}
WRITE(TOUCH_SCK_PIN, LOW);
return result;
}
#endif // HAS_TFT_XPT2046

80
Marlin/src/HAL/STM32F1/tft/xpt2046.h

@ -0,0 +1,80 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 ENABLED(TOUCH_BUTTONS_HW_SPI)
#include <SPI.h>
#endif
#ifndef TOUCH_MISO_PIN
#define TOUCH_MISO_PIN MISO_PIN
#endif
#ifndef TOUCH_MOSI_PIN
#define TOUCH_MOSI_PIN MOSI_PIN
#endif
#ifndef TOUCH_SCK_PIN
#define TOUCH_SCK_PIN SCK_PIN
#endif
#ifndef TOUCH_CS_PIN
#define TOUCH_CS_PIN CS_PIN
#endif
#ifndef TOUCH_INT_PIN
#define TOUCH_INT_PIN -1
#endif
#define XPT2046_DFR_MODE 0x00
#define XPT2046_SER_MODE 0x04
#define XPT2046_CONTROL 0x80
enum XPTCoordinate : uint8_t {
XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE,
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
};
#if !defined(XPT2046_Z1_THRESHOLD)
#define XPT2046_Z1_THRESHOLD 10
#endif
class XPT2046 {
private:
static bool isBusy() { return false; }
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
static inline void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static uint16_t HardwareIO(uint16_t data);
#endif
static uint16_t SoftwareIO(uint16_t data);
static uint16_t IO(uint16_t data = 0);
public:
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static SPIClass SPIx;
#endif
static void Init();
static bool getRawPoint(int16_t *x, int16_t *y);
};

167
Marlin/src/HAL/STM32F1/w25q64.cpp

@ -1,167 +0,0 @@
#include "w25q64.h"
volatile uint8_t *spi_eeprom=shared_mem;
volatile uint32_t spi_cr;
void w25q_set_spi_speed(void){
spi_cr = SPI2->CR1;
spi2_init(SPI_FREQ_18Mhz);
}
void w25q_restore_spi_speed(void){
spi2_init(SPI_FREQ_280KHz);
}
void w25q_init(void){
uint8_t device_id, manuf_id;
uint16_t chip_id;
dwt_init();
spi2_init(SPI_FREQ_4_5Mhz);
//Wake up
W25Q_START;
spi_send(W25X_ReleasePowerDown);
W25Q_STOP;
for(uint32_t i=0; i<0x1000; i++){NOP;} //3us для выхода из power down
//Device ID
W25Q_START;
spi_send(W25X_DeviceID);
for(uint32_t i=0; i<3; i++){spi_send(0);}
device_id = spi_send(0);
W25Q_STOP;
//Jedec ID
W25Q_START;
spi_send(W25X_JedecDeviceID);
manuf_id = spi_send(0);
chip_id = spi_send(0) << 8;
chip_id |= spi_send(0);
DEBUG("W25Q Device ID %0X Manuf ID: %0X Chip ID %0X",device_id,manuf_id,chip_id);
W25Q_STOP;
}
void w25q_read(uint32_t addr, uint8_t *buf, uint32_t len){
if( (len == 0) || (len > SPI_EEPROM_SIZE) ){
ERROR("Len size error: %d",len);
return;
}
addr &= 0xFFFFFF; //24bit address
W25Q_START;
if(len == 1){
spi_send(W25X_ReadData);
spi_send((addr >> 16) & 0xFF);
spi_send((addr >> 8) & 0xFF);
spi_send(addr & 0xFF);
}else{
spi_send(W25X_FastReadData);
spi_send((addr >> 16) & 0xFF);
spi_send((addr >> 8) & 0xFF);
spi_send(addr & 0xFF);
spi_send(0);
}
while (len--){
*buf++ = spi_send(0);
}
W25Q_STOP;
}
void w25q_write(uint32_t addr, uint8_t *buf, uint32_t len){
uint16_t bytes_in_page = SPIFLASH_PAGESIZE - (addr % SPIFLASH_PAGESIZE);
uint16_t offset = 0;
addr &= 0xFFFFFF; //24bit address
while (w25q_read_status() & 1){ //Busy
NOP;
}
//Write Enable
while (len > 0){
uint16_t batch_size = (len <= bytes_in_page) ? len : bytes_in_page;
W25Q_START;
spi_send(W25X_WriteEnable);
W25Q_STOP;
while (w25q_read_status() & 1){ //Busy
NOP;
}
W25Q_START;
spi_send(W25X_PageProgram);
spi_send((addr >> 16) & 0xFF);
spi_send((addr >> 8) & 0xFF);
spi_send(addr & 0xFF);
for (uint32_t i = 0; i < batch_size; i++){
spi_send(((uint8_t*)buf)[offset + i]);
}
W25Q_STOP;
//wait till it's programmed
while (w25q_read_status() & 2){ //Busy
NOP;
}
addr += batch_size;
offset += batch_size;
len -= batch_size;
bytes_in_page = SPIFLASH_PAGESIZE;
}
}
uint8_t w25q_read_status(void){
uint8_t data;
W25Q_START;
spi_send(W25X_ReadStatusReg);
data = spi_send(0);
W25Q_STOP;
return data;
}
void w25q_write_enable(void){
//Write Enable
W25Q_START;
spi_send(W25X_WriteEnable);
W25Q_STOP;
while (w25q_read_status() & 1){ //Busy
NOP;
}
}
void w25q_sector_erase(uint32_t addr){
//Erase 4K
W25Q_START;
spi_send(W25X_SectorErase);
spi_send((addr >> 16) & 0xFF);
spi_send((addr >> 8) & 0xFF);
spi_send(addr & 0xFF);
W25Q_STOP;
while (w25q_read_status() & 1){ //Busy
NOP;
}
}

44
Marlin/src/HAL/STM32F1/w25q64.h

@ -1,44 +0,0 @@
#ifndef W25Q_HAL_H
#define W25Q_HAL_H
#include "../../inc/MarlinConfig.h"
#include "small_spi.h"
#include "../../module/mks_wifi/dwt.h"
#include "../../module/shared_mem/shared_mem.h"
#define SPI_HI_SPEED SPI_FREQ_18Mhz
#define SPI_LOW_SPEED SPI_FREQ_1_125Mhz
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_PageProgram 0x02
#define W25X_BlockErase 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F
#define SPI_EEPROM_SIZE MARLIN_EEPROM_SIZE
#define SPIFLASH_PAGESIZE 256
#define SPI_TIMEOUT 2000 //таймаут на ожидание опереций
#define CHECK_TIMEOUT do{if(dwt_get_timeout() == 0){ERROR("Timeout");return 0;}}while(0)
extern volatile uint8_t *spi_eeprom;
void w25q_init(void);
void w25q_read(uint32_t addr, uint8_t *buf, uint32_t len);
void w25q_write(uint32_t addr, uint8_t *buf, uint32_t len);
uint8_t w25q_read_status(void);
void w25q_write_enable(void);
void w25q_sector_erase(uint32_t addr);
void w25q_set_spi_speed(void);
void w25q_restore_spi_speed(void);
#endif

2
Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp

@ -40,7 +40,7 @@
#include "../../../module/stepper/indirection.h"
#include "../../../module/printcounter.h"
#include "../../../libs/duration_t.h"
#include "../../../libs/hex_print_routines.h"
#include "../../../libs/hex_print.h"
//some default values used in initialization
#define DEFAULT_MICROSTEPPING_VALUE 32

4
Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/STM32F4_F7."
#endif

4
Marlin/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/TEENSY31_32."
#endif

4
Marlin/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h

@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/TEENSY35_36."
#endif

2
Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp

@ -4,7 +4,7 @@
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://www.mozilla.org/en-US/MPL/2.0/
*
* This library was modified, some bugs fixed, stack address validated
* and adapted to be used in Marlin 3D printer firmware as backtracer

4
Marlin/src/HAL/shared/eeprom_if.h

@ -27,3 +27,7 @@
void eeprom_init();
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
#if ENABLED(EEPROM_W25Q)
void eeprom_hw_deinit(void);
#endif

3
Marlin/src/HAL/shared/eeprom_if_i2c.cpp

@ -28,7 +28,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(I2C_EEPROM)
#ifndef EEPROM_AT24C16
#include "eeprom_if.h"
#include <Wire.h>
@ -76,4 +76,3 @@ uint8_t eeprom_read_byte(uint8_t *pos) {
#endif // USE_SHARED_EEPROM
#endif // I2C_EEPROM
#endif

7
Marlin/src/HAL/shared/eeprom_if_spi.cpp

@ -28,7 +28,9 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SPI_EEPROM)
#ifndef EEPROM_W25Q
#if DISABLED(SPI_EEPROM_W25Q)
#include "eeprom_if.h"
void eeprom_init() {}
@ -84,5 +86,6 @@ void eeprom_write_byte(uint8_t* pos, uint8_t value) {
}
#endif // USE_SHARED_EEPROM
#endif // I2C_EEPROM
#endif
#endif // I2C_EEPROM

78
Marlin/src/MarlinCore.cpp

@ -30,6 +30,10 @@
#include "MarlinCore.h"
#if ENABLED(MARLIN_DEV_MODE)
#warning "WARNING! Disable MARLIN_DEV_MODE for the final build!"
#endif
#include "HAL/shared/Delay.h"
#include "HAL/shared/esp_wifi.h"
@ -39,26 +43,27 @@
#include <math.h>
#include "core/utility.h"
#include "lcd/ultralcd.h"
#include "module/motion.h"
#include "module/planner.h"
#include "module/stepper.h"
#include "module/endstops.h"
#include "module/probe.h"
#include "module/temperature.h"
#include "sd/cardreader.h"
#include "module/configuration_store.h"
#include "module/settings.h"
#include "module/printcounter.h" // PrintCounter or Stopwatch
#include "feature/closedloop.h"
#include "module/stepper.h"
#include "module/stepper/indirection.h"
#include "libs/nozzle.h"
#include "gcode/gcode.h"
#include "gcode/parser.h"
#include "gcode/queue.h"
#include "sd/cardreader.h"
#include "lcd/ultralcd.h"
#if HAS_TOUCH_XPT2046
#include "lcd/touch/touch_buttons.h"
#endif
#if HAS_TFT_LVGL_UI
#include "lcd/extui/lib/mks_ui/tft_lvgl_configuration.h"
#include "lcd/extui/lib/mks_ui/draw_ui.h"
@ -80,10 +85,6 @@
#include "feature/direct_stepping.h"
#endif
#if ENABLED(TOUCH_BUTTONS)
#include "feature/touch/xpt2046.h"
#endif
#if ENABLED(HOST_ACTION_COMMANDS)
#include "feature/host_actions.h"
#endif
@ -92,6 +93,10 @@
#include "libs/buzzer.h"
#endif
#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
#include "feature/closedloop.h"
#endif
#if HAS_I2C_DIGIPOT
#include "feature/digipot/digipot.h"
#endif
@ -176,6 +181,10 @@
#include "feature/runout.h"
#endif
#if HAS_Z_SERVO_PROBE
#include "module/probe.h"
#endif
#if ENABLED(HOTEND_IDLE_TIMEOUT)
#include "feature/hotend_idle.h"
#endif
@ -184,7 +193,7 @@
#include "feature/leds/tempstat.h"
#endif
#if HAS_CASE_LIGHT
#if ENABLED(CASE_LIGHT_ENABLE)
#include "feature/caselight.h"
#endif
@ -208,6 +217,10 @@
#include "libs/L64XX/L64XX_Marlin.h"
#endif
#if ENABLED(PASSWORD_FEATURE)
#include "feature/password/password.h"
#endif
PGMSTR(NUL_STR, "");
PGMSTR(M112_KILL_STR, "M112 Shutdown");
PGMSTR(G28_STR, "G28");
@ -444,14 +457,18 @@ void startOrResumeJob() {
#endif
wait_for_heatup = false;
TERN_(POWER_LOSS_RECOVERY, recovery.purge());
#ifdef EVENT_GCODE_SD_STOP
queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
#ifdef EVENT_GCODE_SD_ABORT
queue.inject_P(PSTR(EVENT_GCODE_SD_ABORT));
#endif
TERN_(PASSWORD_AFTER_SD_PRINT_ABORT, password.lock_machine());
}
inline void finishSDPrinting() {
if (queue.enqueue_one_P(PSTR("M1001")))
if (queue.enqueue_one_P(PSTR("M1001"))) {
marlin_state = MF_RUNNING;
TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine());
}
}
#endif // SDSUPPORT
@ -671,7 +688,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
* - Read Buttons and Update the LCD
* - Run i2c Position Encoders
* - Auto-report Temperatures / SD Status
* - Update the Prusa MMU2
* - Update the Průša MMU2
* - Handle Joystick jogging
*/
void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
@ -747,7 +764,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
}
#endif
// Update the Prusa MMU2
// Update the Průša MMU2
TERN_(PRUSA_MMU2, mmu2.mmu_loop());
// Handle Joystick jogging
@ -909,7 +926,7 @@ void setup() {
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
#endif
#if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Put Smart Effector into NORMAL mode
#endif
@ -978,6 +995,10 @@ void setup() {
SETUP_RUN(leds.setup());
#endif
#if ENABLED(NEOPIXEL2_SEPARATE)
SETUP_RUN(leds2.setup());
#endif
#if ENABLED(USE_CONTROLLER_FAN) // Set up fan controller to initialize also the default configurations.
SETUP_RUN(controllerFan.setup());
#endif
@ -1006,7 +1027,7 @@ void setup() {
SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults)
// This also updates variables in the planner, elsewhere
#if ENABLED(TOUCH_BUTTONS)
#if HAS_TOUCH_XPT2046
SETUP_RUN(touch.init());
#endif
@ -1077,15 +1098,11 @@ void setup() {
OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // OFF
#endif
#if HAS_CASE_LIGHT
#if ENABLED(CASE_LIGHT_ENABLE)
#if DISABLED(CASE_LIGHT_USE_NEOPIXEL)
#if DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
if (PWM_PIN(CASE_LIGHT_PIN)) SET_PWM(CASE_LIGHT_PIN); else SET_OUTPUT(CASE_LIGHT_PIN);
#else
SET_OUTPUT(CASE_LIGHT_PIN);
#endif
#endif
SETUP_RUN(update_case_light());
SETUP_RUN(caselight.update_brightness());
#endif
#if ENABLED(MK2_MULTIPLEXER)
@ -1198,13 +1215,20 @@ void setup() {
#endif
#if HAS_TFT_LVGL_UI
if (!card.isMounted()) SETUP_RUN(card.mount()); // Mount SD to load graphics and fonts
#if ENABLED(SDSUPPORT)
if (!card.isMounted()) SETUP_RUN(card.mount()); // Mount SD to load graphics and fonts
#endif
SETUP_RUN(tft_lvgl_init());
#endif
#if ENABLED(PASSWORD_ON_STARTUP)
SETUP_RUN(password.lock_machine()); // Will not proceed until correct password provided
#endif
#if ENABLED(MKS_WIFI)
mks_wifi_init();
#endif
marlin_state = MF_RUNNING;
SETUP_LOG("setup() completed.");

4
Marlin/src/MarlinCore.h

@ -89,8 +89,8 @@ extern bool wait_for_heatup;
#if ENABLED(PSU_CONTROL)
extern bool powersupply_on;
#define PSU_PIN_ON() do{ OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_HIGH); powersupply_on = true; }while(0)
#define PSU_PIN_OFF() do{ OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_HIGH); powersupply_on = false; }while(0)
#define PSU_PIN_ON() do{ OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_STATE); powersupply_on = true; }while(0)
#define PSU_PIN_OFF() do{ OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_STATE); powersupply_on = false; }while(0)
#if ENABLED(AUTO_POWER_CONTROL)
#define PSU_ON() powerManager.power_on()
#define PSU_OFF() powerManager.power_off()

14
Marlin/src/core/boards.h

@ -171,6 +171,7 @@
#define BOARD_STB_11 1508 // STB V1.1
#define BOARD_AZTEEG_X1 1509 // Azteeg X1
#define BOARD_ANET_10 1510 // Anet 1.0 (Melzi clone)
#define BOARD_ZMIB_V2 1511 // ZoneStar ZMIB V2
//
// Other ATmega644P, ATmega644, ATmega1284P
@ -312,7 +313,8 @@
#define BOARD_CHITU3D_V5 4031 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CHITU3D_V6 4032 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CREALITY_V4 4033 // Creality v4.x (STM32F103RE)
#define BOARD_TRIGORILLA_PRO 4034 // Trigorilla Pro (STM32F103ZET6)
#define BOARD_CREALITY_V427 4034 // Creality v4.2.7 (STM32F103RE)
#define BOARD_TRIGORILLA_PRO 4035 // Trigorilla Pro (STM32F103ZET6)
//
// ARM Cortex-M4F
@ -343,8 +345,9 @@
#define BOARD_LERDGE_X 4215 // Lerdge X (STM32F407VE)
#define BOARD_VAKE403D 4216 // VAkE 403D (STM32F446VET6)
#define BOARD_FYSETC_S6 4217 // FYSETC S6 board
#define BOARD_FLYF407ZG 4218 // FLYF407ZG board (STM32F407ZG)
#define BOARD_MKS_ROBIN2 4219 // MKS_ROBIN2 (STM32F407ZE)
#define BOARD_FYSETC_S6_V2_0 4218 // FYSETC S6 v2.0 board
#define BOARD_FLYF407ZG 4219 // FLYF407ZG board (STM32F407ZG)
#define BOARD_MKS_ROBIN2 4220 // MKS_ROBIN2 (STM32F407ZE)
//
// ARM Cortex M7
@ -366,6 +369,11 @@
//
#define BOARD_AGCM4_RAMPS_144 6100 // RAMPS 1.4.4
//
// Custom board
//
#define BOARD_CUSTOM 9998 // Custom pins definition for development and/or rare boards
//
// Simulations
//

11
Marlin/src/core/language.h

@ -266,6 +266,13 @@
#define STR_DEBUG_COMMUNICATION "COMMUNICATION"
#define STR_DEBUG_LEVELING "LEVELING"
#define STR_PRINTER_LOCKED "Printer locked! (Unlock with M511 or LCD)"
#define STR_WRONG_PASSWORD "Incorrect Password"
#define STR_PASSWORD_TOO_LONG "Password too long"
#define STR_PASSWORD_REMOVED "Password removed"
#define STR_REMINDER_SAVE_SETTINGS "Remember to save!"
#define STR_PASSWORD_SET "Password is "
// LCD Menu Messages
#define LANGUAGE_DATA_INCL_(M) STRINGIFY_(fontdata/langdata_##M.h)
@ -346,7 +353,7 @@
*
*/
#if ENABLED(NUMBER_TOOLS_FROM_0)
#define LCD_FIRST_TOOL '0'
#define LCD_FIRST_TOOL 0
#define LCD_STR_N0 "0"
#define LCD_STR_N1 "1"
#define LCD_STR_N2 "2"
@ -356,7 +363,7 @@
#define LCD_STR_N6 "6"
#define LCD_STR_N7 "7"
#else
#define LCD_FIRST_TOOL '1'
#define LCD_FIRST_TOOL 1
#define LCD_STR_N0 "1"
#define LCD_STR_N1 "2"
#define LCD_STR_N2 "3"

51
Marlin/src/core/macros.h

@ -342,15 +342,22 @@
#endif
// Macros for adding
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INC_9 10
#define INC_10 11
#define INC_11 12
#define INC_12 13
#define INC_13 14
#define INC_14 15
#define INC_15 16
#define INCREMENT_(n) INC_##n
#define INCREMENT(n) INCREMENT_(n)
@ -367,16 +374,22 @@
#define ADD10(N) ADD5(ADD5(N))
// Macros for subtracting
#define DEC_0 0
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DEC_0 0
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DEC_10 9
#define DEC_11 10
#define DEC_12 11
#define DEC_13 12
#define DEC_14 13
#define DEC_15 14
#define DECREMENT_(n) DEC_##n
#define DECREMENT(n) DECREMENT_(n)

0
Marlin/src/core/multi_language.cpp

5
Marlin/src/feature/babystep.cpp

@ -26,7 +26,8 @@
#include "babystep.h"
#include "../MarlinCore.h"
#include "../module/planner.h"
#include "../module/motion.h" // for axes_should_home()
#include "../module/planner.h" // for axis_steps_per_mm[]
#include "../module/stepper.h"
#if ENABLED(BABYSTEP_ALWAYS_AVAILABLE)
@ -54,7 +55,7 @@ void Babystep::add_mm(const AxisEnum axis, const float &mm) {
}
void Babystep::add_steps(const AxisEnum axis, const int16_t distance) {
if (DISABLED(BABYSTEP_WITHOUT_HOMING) && !TEST(axis_known_position, axis)) return;
if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axes_should_home(_BV(axis))) return;
accum += distance; // Count up babysteps for the UI
steps[BS_AXIS_IND(axis)] += distance;

2
Marlin/src/feature/bedlevel/ubl/ubl.cpp

@ -31,7 +31,7 @@
#include "../../../MarlinCore.h"
#include "../../../gcode/gcode.h"
#include "../../../module/configuration_store.h"
#include "../../../module/settings.h"
#include "../../../module/planner.h"
#include "../../../module/motion.h"
#include "../../../module/probe.h"

6
Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp

@ -28,8 +28,8 @@
#include "../../../MarlinCore.h"
#include "../../../HAL/shared/eeprom_api.h"
#include "../../../libs/hex_print_routines.h"
#include "../../../module/configuration_store.h"
#include "../../../libs/hex_print.h"
#include "../../../module/settings.h"
#include "../../../lcd/ultralcd.h"
#include "../../../module/stepper.h"
#include "../../../module/planner.h"
@ -321,7 +321,7 @@
// Check for commands that require the printer to be homed
if (may_move) {
planner.synchronize();
if (axes_need_homing()) gcode.home_all_axes();
if (axes_should_home()) gcode.home_all_axes();
TERN_(HAS_MULTI_HOTEND, if (active_extruder) tool_change(0));
}

4
Marlin/src/feature/binary_protocol.cpp → Marlin/src/feature/binary_stream.cpp

@ -25,7 +25,7 @@
#if ENABLED(BINARY_FILE_TRANSFER)
#include "../sd/cardreader.h"
#include "binary_protocol.h"
#include "binary_stream.h"
char* SDFileTransferProtocol::Packet::Open::data = nullptr;
size_t SDFileTransferProtocol::data_waiting, SDFileTransferProtocol::transfer_timeout, SDFileTransferProtocol::idle_timeout;
@ -33,4 +33,4 @@ bool SDFileTransferProtocol::transfer_active, SDFileTransferProtocol::dummy_tran
BinaryStream binaryStream[NUM_SERIAL];
#endif // BINARY_FILE_TRANSFER
#endif

0
Marlin/src/feature/binary_protocol.h → Marlin/src/feature/binary_stream.h

48
Marlin/src/feature/caselight.cpp

@ -22,14 +22,17 @@
#include "../inc/MarlinConfig.h"
#if HAS_CASE_LIGHT
#if ENABLED(CASE_LIGHT_ENABLE)
uint8_t case_light_brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS;
bool case_light_on = CASE_LIGHT_DEFAULT_ON;
#include "caselight.h"
CaseLight caselight;
uint8_t CaseLight::brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS;
bool CaseLight::on = CASE_LIGHT_DEFAULT_ON;
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
#include "leds/leds.h"
LEDColor case_light_color =
LEDColor CaseLight::color =
#ifdef CASE_LIGHT_NEOPIXEL_COLOR
CASE_LIGHT_NEOPIXEL_COLOR
#else
@ -38,34 +41,33 @@ bool case_light_on = CASE_LIGHT_DEFAULT_ON;
;
#endif
/**
* The following are needed because ARM chips ignore a "WRITE(CASE_LIGHT_PIN,x)" command to the pins that
* are directly controlled by the PWM module. In order to turn them off the brightness level needs to be
* set to off. Since we can't use the pwm register to save the last brightness level we need a variable
* to save it.
*/
uint8_t case_light_brightness_sav; // saves brighness info so can restore when "M355 S1" received
bool case_light_arg_flag; // flag to notify if S or P argument type
#ifndef INVERT_CASE_LIGHT
#define INVERT_CASE_LIGHT false
#endif
void update_case_light() {
void CaseLight::update(const bool sflag) {
/**
* The brightness_sav (and sflag) is needed because ARM chips ignore
* a "WRITE(CASE_LIGHT_PIN,x)" command to the pins that are directly
* controlled by the PWM module. In order to turn them off the brightness
* level needs to be set to OFF. Since we can't use the PWM register to
* save the last brightness level we need a variable to save it.
*/
static uint8_t brightness_sav; // Save brightness info for restore on "M355 S1"
if (!(case_light_arg_flag && !case_light_on))
case_light_brightness_sav = case_light_brightness; // save brightness except if this is an S0 argument
if (case_light_arg_flag && case_light_on)
case_light_brightness = case_light_brightness_sav; // restore last brightens if this is an S1 argument
if (on || !sflag)
brightness_sav = brightness; // Save brightness except for M355 S0
if (sflag && on)
brightness = brightness_sav; // Restore last brightness for M355 S1
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL) || DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
const uint8_t i = case_light_on ? case_light_brightness : 0, n10ct = INVERT_CASE_LIGHT ? 255 - i : i;
const uint8_t i = on ? brightness : 0, n10ct = INVERT_CASE_LIGHT ? 255 - i : i;
#endif
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
leds.set_color(
MakeLEDColor(case_light_color.r, case_light_color.g, case_light_color.b, case_light_color.w, n10ct),
MakeLEDColor(color.r, color.g, color.b, color.w, n10ct),
false
);
@ -83,11 +85,11 @@ void update_case_light() {
else
#endif
{
const bool s = case_light_on ? !INVERT_CASE_LIGHT : INVERT_CASE_LIGHT;
const bool s = on ? !INVERT_CASE_LIGHT : INVERT_CASE_LIGHT;
WRITE(CASE_LIGHT_PIN, s ? HIGH : LOW);
}
#endif // !CASE_LIGHT_USE_NEOPIXEL
}
#endif // HAS_CASE_LIGHT
#endif // CASE_LIGHT_ENABLE

26
Marlin/src/feature/caselight.h

@ -21,9 +21,25 @@
*/
#pragma once
extern uint8_t case_light_brightness;
extern bool case_light_on;
extern uint8_t case_light_brightness_sav; // saves brighness info when case_light_on is false
extern bool case_light_arg_flag; // flag to notify if S or P argument type
#include "../inc/MarlinConfigPre.h"
void update_case_light();
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
#include "leds/leds.h"
#endif
class CaseLight {
public:
static uint8_t brightness;
static bool on;
static void update(const bool sflag);
static inline void update_brightness() { update(false); }
static inline void update_enabled() { update(true); }
private:
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
static LEDColor color;
#endif
};
extern CaseLight caselight;

2
Marlin/src/feature/dac/dac_mcp4728.cpp

@ -27,7 +27,7 @@
* https://ww1.microchip.com/downloads/en/DeviceDoc/22187a.pdf
*
* For discussion and feedback, please go to:
* https://arduino.cc/forum/index.php/topic,51842.0.html
* https://forum.arduino.cc/index.php/topic,51842.0.html
*/
#include "../../inc/MarlinConfig.h"

49
Marlin/src/feature/direct_stepping.cpp

@ -56,9 +56,6 @@ namespace DirectStepping {
template<typename Cfg>
volatile bool SerialPageManager<Cfg>::page_states_dirty;
template<typename Cfg>
millis_t SerialPageManager<Cfg>::next_response;
template<typename Cfg>
uint8_t SerialPageManager<Cfg>::pages[Cfg::NUM_PAGES][Cfg::PAGE_SIZE];
@ -80,7 +77,6 @@ namespace DirectStepping {
page_states[i] = PageState::FREE;
fatal_error = false;
next_response = 0;
state = State::NEWLINE;
page_states_dirty = false;
@ -181,15 +177,8 @@ namespace DirectStepping {
return;
}
// Runs on a set interval also, as responses may get lost.
if (next_response && next_response < millis()) {
page_states_dirty = true;
}
if (!page_states_dirty) return;
page_states_dirty = false;
next_response = millis() + Cfg::RESPONSE_INTERVAL_MS;
SERIAL_ECHO(Cfg::CONTROL_CHAR);
constexpr int state_bits = 2;
@ -238,29 +227,29 @@ const uint8_t segment_table[DirectStepping::Config::NUM_SEGMENTS][DirectStepping
#if STEPPER_PAGE_FORMAT == SP_4x4D_128
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7
{ 1, 1, 1, 1, 1, 1, 1 }, // 0 = -7
{ 1, 1, 1, 0, 1, 1, 1 }, // 1 = -6
{ 1, 1, 1, 0, 1, 0, 1 }, // 2 = -5
{ 1, 1, 0, 1, 0, 1, 0 }, // 3 = -4
{ 1, 1, 0, 0, 1, 0, 0 }, // 4 = -3
{ 0, 0, 1, 0, 0, 0, 1 }, // 5 = -2
{ 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1
{ 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0
{ 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1
{ 0, 0, 1, 0, 0, 0, 1 }, // 9 = 2
{ 1, 1, 0, 0, 1, 0, 0 }, // 10 = 3
{ 1, 1, 0, 1, 0, 1, 0 }, // 11 = 4
{ 1, 1, 1, 0, 1, 0, 1 }, // 12 = 5
{ 1, 1, 1, 0, 1, 1, 1 }, // 13 = 6
{ 1, 1, 1, 1, 1, 1, 1 }, // 14 = 7
{ 0 }
#elif STEPPER_PAGE_FORMAT == SP_4x2_256
{ 0, 0, 0, 0 }, // 0
{ 0, 1, 0, 0 }, // 1
{ 1, 0, 1, 0 }, // 2
{ 1, 1, 1, 0 }, // 3
{ 0, 0, 0 }, // 0
{ 0, 1, 0 }, // 1
{ 1, 0, 1 }, // 2
{ 1, 1, 1 }, // 3
#elif STEPPER_PAGE_FORMAT == SP_4x1_512

6
Marlin/src/feature/direct_stepping.h

@ -70,7 +70,6 @@ namespace DirectStepping {
static volatile PageState page_states[Cfg::NUM_PAGES];
static volatile bool page_states_dirty;
static millis_t next_response;
static uint8_t pages[Cfg::NUM_PAGES][Cfg::PAGE_SIZE];
static uint8_t checksum;
@ -94,14 +93,11 @@ namespace DirectStepping {
static constexpr int DIRECTIONAL = dir ? 1 : 0;
static constexpr int SEGMENTS = segments;
static constexpr int RAW = (BITS_SEGMENT == 1) ? 1 : 0;
static constexpr int NUM_SEGMENTS = 1 << BITS_SEGMENT;
static constexpr int SEGMENT_STEPS = 1 << (BITS_SEGMENT - DIRECTIONAL - RAW);
static constexpr int SEGMENT_STEPS = (1 << (BITS_SEGMENT - DIRECTIONAL)) - 1;
static constexpr int TOTAL_STEPS = SEGMENT_STEPS * SEGMENTS;
static constexpr int PAGE_SIZE = (NUM_AXES * BITS_SEGMENT * SEGMENTS) / 8;
static constexpr millis_t RESPONSE_INTERVAL_MS = 50;
typedef typename TypeSelector<(PAGE_SIZE>256), uint16_t, uint8_t>::type write_byte_idx_t;
typedef typename TypeSelector<(NUM_PAGES>256), uint16_t, uint8_t>::type page_idx_t;
};

2
Marlin/src/feature/e_parser.cpp

@ -21,7 +21,7 @@
*/
/**
* emergency_parser.cpp - Intercept special commands directly in the serial stream
* e_parser.cpp - Intercept special commands directly in the serial stream
*/
#include "../inc/MarlinConfigPre.h"

2
Marlin/src/feature/e_parser.h

@ -22,7 +22,7 @@
#pragma once
/**
* emergency_parser.h - Intercept special commands directly in the serial stream
* e_parser.h - Intercept special commands directly in the serial stream
*/
#include "../inc/MarlinConfigPre.h"

60
Marlin/src/feature/leds/leds.cpp

@ -44,11 +44,8 @@
#if ENABLED(LED_COLOR_PRESETS)
const LEDColor LEDLights::defaultLEDColor = MakeLEDColor(
LED_USER_PRESET_RED,
LED_USER_PRESET_GREEN,
LED_USER_PRESET_BLUE,
LED_USER_PRESET_WHITE,
LED_USER_PRESET_BRIGHTNESS
LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE,
LED_USER_PRESET_WHITE, LED_USER_PRESET_BRIGHTNESS
);
#endif
@ -117,24 +114,22 @@ void LEDLights::set_color(const LEDColor &incol
// This variant uses 3-4 separate pins for the RGB(W) components.
// If the pins can do PWM then their intensity will be set.
#define UPDATE_RGBW(C,c) do { if (PWM_PIN(RGB_LED_##C##_PIN)) \
#define UPDATE_RGBW(C,c) do { \
if (PWM_PIN(RGB_LED_##C##_PIN)) \
analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \
else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); }while(0)
UPDATE_RGBW(R,r);
UPDATE_RGBW(G,g);
UPDATE_RGBW(B,b);
else \
WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); \
}while(0)
UPDATE_RGBW(R,r); UPDATE_RGBW(G,g); UPDATE_RGBW(B,b);
#if ENABLED(RGBW_LED)
UPDATE_RGBW(W,w);
#endif
#endif
#if ENABLED(PCA9632)
// Update I2C LED driver
pca9632_set_led_color(incol);
#endif
TERN_(PCA9533, PCA9533_setColor(incol.r, incol.g, incol.b));
// Update I2C LED driver
TERN_(PCA9632, PCA9632_set_led_color(incol));
TERN_(PCA9533, PCA9533_set_rgb(incol.r, incol.g, incol.b));
#if EITHER(LED_CONTROL_MENU, PRINTER_EVENT_LEDS)
// Don't update the color when OFF
@ -161,4 +156,35 @@ void LEDLights::set_color(const LEDColor &incol
#endif
#endif // HAS_COLOR_LEDS
#if ENABLED(NEOPIXEL2_SEPARATE)
#if ENABLED(NEO2_COLOR_PRESETS)
const LEDColor LEDLights2::defaultLEDColor = MakeLEDColor(
NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE,
NEO2_USER_PRESET_WHITE, NEO2_USER_PRESET_BRIGHTNESS
);
#endif
#if ENABLED(LED_CONTROL_MENU)
LEDColor LEDLights2::color;
bool LEDLights2::lights_on;
#endif
LEDLights2 leds2;
void LEDLights2::setup() {
neo2.init();
TERN_(NEO2_USER_PRESET_STARTUP, set_default());
}
void LEDLights2::set_color(const LEDColor &incol) {
const uint32_t neocolor = LEDColorWhite() == incol
? neo2.Color(NEO2_WHITE)
: neo2.Color(incol.r, incol.g, incol.b, incol.w);
neo2.set_brightness(incol.i);
neo2.set_color(neocolor);
}
#endif // NEOPIXEL2_SEPARATE
#endif // HAS_COLOR_LEDS

53
Marlin/src/feature/leds/leds.h

@ -104,11 +104,7 @@ typedef struct LEDColor {
bool operator!=(const LEDColor &right) { return !operator==(right); }
bool is_off() const {
return 3 > r + g + b
#if HAS_WHITE_LED
+ w
#endif
;
return 3 > r + g + b + TERN0(HAS_WHITE_LED, w);
}
} LEDColor;
@ -156,14 +152,12 @@ public:
#endif
);
inline void set_color(uint8_t r, uint8_t g, uint8_t b
static inline void set_color(uint8_t r, uint8_t g, uint8_t b
#if HAS_WHITE_LED
, uint8_t w=0
#if ENABLED(NEOPIXEL_LED)
, uint8_t i=NEOPIXEL_BRIGHTNESS
#endif
#endif
#if ENABLED(NEOPIXEL_LED)
, uint8_t i=NEOPIXEL_BRIGHTNESS
, bool isSequence=false
#endif
) {
@ -216,3 +210,44 @@ public:
};
extern LEDLights leds;
#if ENABLED(NEOPIXEL2_SEPARATE)
class LEDLights2 {
public:
LEDLights2() {}
static void setup(); // init()
static void set_color(const LEDColor &color);
inline void set_color(uint8_t r, uint8_t g, uint8_t b, uint8_t w=0, uint8_t i=NEOPIXEL2_BRIGHTNESS) {
set_color(MakeLEDColor(r, g, b, w, i));
}
static inline void set_off() { set_color(LEDColorOff()); }
static inline void set_green() { set_color(LEDColorGreen()); }
static inline void set_white() { set_color(LEDColorWhite()); }
#if ENABLED(NEO2_COLOR_PRESETS)
static const LEDColor defaultLEDColor;
static inline void set_default() { set_color(defaultLEDColor); }
static inline void set_red() { set_color(LEDColorRed()); }
static inline void set_orange() { set_color(LEDColorOrange()); }
static inline void set_yellow() { set_color(LEDColorYellow()); }
static inline void set_blue() { set_color(LEDColorBlue()); }
static inline void set_indigo() { set_color(LEDColorIndigo()); }
static inline void set_violet() { set_color(LEDColorViolet()); }
#endif
#if ENABLED(LED_CONTROL_MENU)
static LEDColor color; // last non-off color
static bool lights_on; // the last set color was "on"
static void toggle(); // swap "off" with color
static inline void update() { set_color(color); }
#endif
};
extern LEDLights2 leds2;
#endif // NEOPIXEL2_SEPARATE

67
Marlin/src/feature/leds/neopixel.cpp

@ -30,7 +30,7 @@
#include "neopixel.h"
#if ENABLED(NEOPIXEL_STARTUP_TEST)
#if EITHER(NEOPIXEL_STARTUP_TEST, NEOPIXEL2_STARTUP_TEST)
#include "../../core/utility.h"
#endif
@ -38,7 +38,7 @@ Marlin_NeoPixel neo;
int8_t Marlin_NeoPixel::neoindex;
Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800)
#if MULTIPLE_NEOPIXEL_TYPES
#if CONJOINED_NEOPIXEL
, Marlin_NeoPixel::adaneo2(NEOPIXEL_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE + NEO_KHZ800)
#endif
;
@ -53,9 +53,9 @@ Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIX
#endif
void Marlin_NeoPixel::set_color(const uint32_t color) {
if (get_neo_index() >= 0) {
set_pixel_color(get_neo_index(), color);
set_neo_index(-1);
if (neoindex >= 0) {
set_pixel_color(neoindex, color);
neoindex = -1;
}
else {
for (uint16_t i = 0; i < pixels(); ++i) {
@ -78,18 +78,18 @@ void Marlin_NeoPixel::set_color_startup(const uint32_t color) {
}
void Marlin_NeoPixel::init() {
set_neo_index(-1); // -1 .. NEOPIXEL_PIXELS-1 range
neoindex = -1; // -1 .. NEOPIXEL_PIXELS-1 range
set_brightness(NEOPIXEL_BRIGHTNESS); // 0 .. 255 range
begin();
show(); // initialize to all off
#if ENABLED(NEOPIXEL_STARTUP_TEST)
set_color_startup(adaneo1.Color(255, 0, 0, 0)); // red
safe_delay(1000);
safe_delay(500);
set_color_startup(adaneo1.Color(0, 255, 0, 0)); // green
safe_delay(1000);
safe_delay(500);
set_color_startup(adaneo1.Color(0, 0, 255, 0)); // blue
safe_delay(1000);
safe_delay(500);
#endif
#ifdef NEOPIXEL_BKGD_LED_INDEX
@ -120,4 +120,53 @@ bool Marlin_NeoPixel::set_led_color(const uint8_t r, const uint8_t g, const uint
}
#endif
#if ENABLED(NEOPIXEL2_SEPARATE)
Marlin_NeoPixel2 neo2;
int8_t Marlin_NeoPixel2::neoindex;
Adafruit_NeoPixel Marlin_NeoPixel2::adaneo(NEOPIXEL2_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE);
void Marlin_NeoPixel2::set_color(const uint32_t color) {
if (neoindex >= 0) {
set_pixel_color(neoindex, color);
neoindex = -1;
}
else {
for (uint16_t i = 0; i < pixels(); ++i)
set_pixel_color(i, color);
}
show();
}
void Marlin_NeoPixel2::set_color_startup(const uint32_t color) {
for (uint16_t i = 0; i < pixels(); ++i)
set_pixel_color(i, color);
show();
}
void Marlin_NeoPixel2::init() {
neoindex = -1; // -1 .. NEOPIXEL2_PIXELS-1 range
set_brightness(NEOPIXEL2_BRIGHTNESS); // 0 .. 255 range
begin();
show(); // initialize to all off
#if ENABLED(NEOPIXEL2_STARTUP_TEST)
set_color_startup(adaneo.Color(255, 0, 0, 0)); // red
safe_delay(500);
set_color_startup(adaneo.Color(0, 255, 0, 0)); // green
safe_delay(500);
set_color_startup(adaneo.Color(0, 0, 255, 0)); // blue
safe_delay(500);
#endif
#if ENABLED(NEO2_USER_PRESET_STARTUP)
set_color(adaneo.Color(NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE, NEO2_USER_PRESET_WHITE));
#else
set_color(adaneo.Color(0, 0, 0, 0));
#endif
}
#endif // NEOPIXEL2_SEPARATE
#endif // NEOPIXEL_LED

79
Marlin/src/feature/leds/neopixel.h

@ -22,7 +22,7 @@
#pragma once
/**
* Neopixel support
* NeoPixel support
*/
// ------------------------
@ -38,10 +38,14 @@
// Defines
// ------------------------
#if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE
#if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE && DISABLED(NEOPIXEL2_SEPARATE)
#define MULTIPLE_NEOPIXEL_TYPES 1
#endif
#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES)
#define CONJOINED_NEOPIXEL 1
#endif
#if NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR
#define NEOPIXEL_IS_RGB 1
#else
@ -61,44 +65,49 @@
class Marlin_NeoPixel {
private:
static Adafruit_NeoPixel adaneo1
#if MULTIPLE_NEOPIXEL_TYPES
#if CONJOINED_NEOPIXEL
, adaneo2
#endif
;
static int8_t neoindex;
public:
static int8_t neoindex;
static void init();
static void set_color_startup(const uint32_t c);
static void set_color(const uint32_t c);
FORCE_INLINE static void set_neo_index(const int8_t neoIndex) { neoindex = neoIndex; }
FORCE_INLINE static int8_t get_neo_index() { return neoindex; }
#ifdef NEOPIXEL_BKGD_LED_INDEX
static void set_color_background();
#endif
static inline void begin() {
adaneo1.begin();
TERN_(MULTIPLE_NEOPIXEL_TYPES, adaneo2.begin());
TERN_(CONJOINED_NEOPIXEL, adaneo2.begin());
}
static inline void set_pixel_color(const uint16_t n, const uint32_t c) {
adaneo1.setPixelColor(n, c);
TERN_(MULTIPLE_NEOPIXEL_TYPES, adaneo2.setPixelColor(n, c));
#if ENABLED(NEOPIXEL2_INSERIES)
if (n >= NEOPIXEL_PIXELS) adaneo2.setPixelColor(n - (NEOPIXEL_PIXELS), c);
else adaneo1.setPixelColor(n, c);
#else
adaneo1.setPixelColor(n, c);
#if MULTIPLE_NEOPIXEL_TYPES
adaneo2.setPixelColor(n, c);
#endif
#endif
}
static inline void set_brightness(const uint8_t b) {
adaneo1.setBrightness(b);
TERN_(MULTIPLE_NEOPIXEL_TYPES, adaneo2.setBrightness(b));
TERN_(CONJOINED_NEOPIXEL, adaneo2.setBrightness(b));
}
static inline void show() {
adaneo1.show();
#if PIN_EXISTS(NEOPIXEL2)
#if MULTIPLE_NEOPIXEL_TYPES
#if CONJOINED_NEOPIXEL
adaneo2.show();
#else
adaneo1.setPin(NEOPIXEL2_PIN);
@ -113,7 +122,7 @@ public:
#endif
// Accessors
static inline uint16_t pixels() { return adaneo1.numPixels(); }
static inline uint16_t pixels() { TERN(NEOPIXEL2_INSERIES, return adaneo1.numPixels() * 2, return adaneo1.numPixels()); }
static inline uint8_t brightness() { return adaneo1.getBrightness(); }
static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
return adaneo1.Color(r, g, b, w);
@ -121,3 +130,47 @@ public:
};
extern Marlin_NeoPixel neo;
// Neo pixel channel 2
#if ENABLED(NEOPIXEL2_SEPARATE)
#if NEOPIXEL2_TYPE == NEO_RGB || NEOPIXEL2_TYPE == NEO_RBG || NEOPIXEL2_TYPE == NEO_GRB || NEOPIXEL2_TYPE == NEO_GBR || NEOPIXEL2_TYPE == NEO_BRG || NEOPIXEL2_TYPE == NEO_BGR
#define NEOPIXEL2_IS_RGB 1
#else
#define NEOPIXEL2_IS_RGBW 1
#endif
#if NEOPIXEL2_IS_RGB
#define NEO2_WHITE 255, 255, 255, 0
#else
#define NEO2_WHITE 0, 0, 0, 255
#endif
class Marlin_NeoPixel2 {
private:
static Adafruit_NeoPixel adaneo;
public:
static int8_t neoindex;
static void init();
static void set_color_startup(const uint32_t c);
static void set_color(const uint32_t c);
static inline void begin() { adaneo.begin(); }
static inline void set_pixel_color(const uint16_t n, const uint32_t c) { adaneo.setPixelColor(n, c); }
static inline void set_brightness(const uint8_t b) { adaneo.setBrightness(b); }
static inline void show() { adaneo.show(); }
// Accessors
static inline uint16_t pixels() { return adaneo.numPixels();}
static inline uint8_t brightness() { return adaneo.getBrightness(); }
static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
return adaneo.Color(r, g, b, w);
}
};
extern Marlin_NeoPixel2 neo2;
#endif // NEOPIXEL2_SEPARATE

2
Marlin/src/feature/leds/pca9533.cpp

@ -62,7 +62,7 @@ void PCA9533_setOff() {
PCA9533_writeRegister(PCA9533_REG_SEL, 0);
}
void PCA9533_setColor(uint8_t red, uint8_t green, uint8_t blue) {
void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue) {
uint8_t r_pwm0 = 0; // Register data - PWM value
uint8_t r_pwm1 = 0; // Register data - PWM value

2
Marlin/src/feature/leds/pca9533.h

@ -55,5 +55,5 @@
void PCA9533_init();
void PCA9533_reset();
void PCA9533_setColor(uint8_t red, uint8_t green, uint8_t blue);
void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue);
void PCA9533_setOff();

4
Marlin/src/feature/leds/pca9632.cpp

@ -120,7 +120,7 @@ static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const
}
#endif
void pca9632_set_led_color(const LEDColor &color) {
void PCA9632_set_led_color(const LEDColor &color) {
Wire.begin();
if (!PCA_init) {
PCA_init = 1;
@ -138,7 +138,7 @@ void pca9632_set_led_color(const LEDColor &color) {
#if ENABLED(PCA9632_BUZZER)
void pca9632_buzz(const long, const uint16_t) {
void PCA9632_buzz(const long, const uint16_t) {
uint8_t data[] = PCA9632_BUZZER_DATA;
Wire.beginTransmission(I2C_ADDRESS(PCA9632_ADDRESS));
Wire.write(data, sizeof(data));

4
Marlin/src/feature/leds/pca9632.h

@ -29,9 +29,9 @@
struct LEDColor;
typedef LEDColor LEDColor;
void pca9632_set_led_color(const LEDColor &color);
void PCA9632_set_led_color(const LEDColor &color);
#if ENABLED(PCA9632_BUZZER)
#include <stdint.h>
void pca9632_buzz(const long, const uint16_t);
void PCA9632_buzz(const long, const uint16_t);
#endif

2
Marlin/src/feature/leds/printer_event_leds.cpp

@ -21,7 +21,7 @@
*/
/**
* printer_event_leds.cpp - LED color changing based on printer status
* feature/leds/printer_event_leds.cpp - LED color changing based on printer status
*/
#include "../../inc/MarlinConfigPre.h"

2
Marlin/src/feature/leds/printer_event_leds.h

@ -22,7 +22,7 @@
#pragma once
/**
* printer_event_leds.h - LED color changing based on printer status
* feature/leds/printer_event_leds.h - LED color changing based on printer status
*/
#include "leds.h"

58
Marlin/src/feature/password/password.cpp

@ -0,0 +1,58 @@
/**
* 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(PASSWORD_FEATURE)
#include "password.h"
#include "../../gcode/gcode.h"
#include "../../core/serial.h"
Password password;
// public:
bool Password::is_set, Password::is_locked;
uint32_t Password::value, Password::value_entry;
//
// Authenticate user with password.
// Called from Setup, after SD Prinitng Stops/Aborts, and M510
//
void Password::lock_machine() {
is_locked = true;
TERN_(HAS_LCD_MENU, authenticate_user(ui.status_screen, screen_password_entry));
}
//
// Authentication check
//
void Password::authentication_check() {
if (value_entry == value)
is_locked = false;
else
SERIAL_ECHOLNPGM(STR_WRONG_PASSWORD);
TERN_(HAS_LCD_MENU, authentication_done());
}
#endif // PASSWORD_FEATURE

57
Marlin/src/feature/password/password.h

@ -0,0 +1,57 @@
/**
* 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 "../../lcd/ultralcd.h"
class Password {
public:
static bool is_set, is_locked;
static uint32_t value, value_entry;
Password() { is_locked = false; }
static void lock_machine();
#if HAS_LCD_MENU
static void access_menu_password();
static void authentication_check();
static void authentication_done();
static void media_gatekeeper();
private:
static void authenticate_user(const screenFunc_t, const screenFunc_t);
static void menu_password();
static void menu_password_entry();
static void screen_password_entry();
static void screen_set_password();
static void start_over();
static void digit_entered();
static void set_password_done();
static void menu_password_report();
static void remove_password();
#endif
};
extern Password password;

7
Marlin/src/feature/pause.cpp

@ -413,7 +413,7 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
unscaled_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE);
// Park the nozzle by moving up by z_lift and then moving to (x_pos, y_pos)
if (!axes_need_homing())
if (!axes_should_home())
nozzle.park(0, park_point);
#if ENABLED(DUAL_X_CARRIAGE)
@ -582,6 +582,9 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_RESUME));
// Check Temperature before moving hotend
ensure_safe_temperature();
// Retract to prevent oozing
unscaled_e_move(-(PAUSE_PARK_RETRACT_LENGTH), feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
@ -594,8 +597,6 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
// Unretract
unscaled_e_move(PAUSE_PARK_RETRACT_LENGTH, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
ensure_safe_temperature();
// Intelligent resuming
#if ENABLED(FWRETRACT)
// If retracted before goto pause

5
Marlin/src/feature/power.cpp

@ -59,7 +59,6 @@ bool Power::is_power_needed() {
// If any of the drivers or the bed are enabled...
if (X_ENABLE_READ() == X_ENABLE_ON || Y_ENABLE_READ() == Y_ENABLE_ON || Z_ENABLE_READ() == Z_ENABLE_ON
|| TERN0(HAS_HEATED_BED, thermalManager.temp_bed.soft_pwm_amount > 0)
#if HAS_X2_ENABLE
|| X2_ENABLE_READ() == X_ENABLE_ON
#endif
@ -75,8 +74,8 @@ bool Power::is_power_needed() {
#endif
) return true;
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0) return true;
if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0)) return true;
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true;
if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true;
#if HAS_HOTEND && AUTO_POWER_E_TEMP
HOTEND_LOOP() if (thermalManager.degHotend(e) >= AUTO_POWER_E_TEMP) return true;

4
Marlin/src/feature/powerloss.cpp

@ -21,7 +21,7 @@
*/
/**
* power_loss_recovery.cpp - Resume an SD print after power-loss
* feature/powerloss.cpp - Resume an SD print after power-loss
*/
#include "../inc/MarlinConfigPre.h"
@ -365,7 +365,7 @@ void PrintJobRecovery::resume() {
#endif
// Pretend that all axes are homed
axis_homed = axis_known_position = xyz_bits;
set_all_homed();
// Recover volumetric extrusion state
#if DISABLED(NO_VOLUMETRICS)

2
Marlin/src/feature/powerloss.h

@ -22,7 +22,7 @@
#pragma once
/**
* power_loss_recovery.h - Resume an SD print after power-loss
* feature/powerloss.h - Resume an SD print after power-loss
*/
#include "../sd/cardreader.h"

8
Marlin/src/feature/runout.cpp

@ -44,14 +44,6 @@ bool FilamentMonitorBase::enabled = true,
#include "../module/tool_change.h"
#endif
/**
* Called by FilamentSensorSwitch::run when filament is detected.
* Called by FilamentSensorEncoder::block_completed when motion is detected.
*/
void FilamentSensorBase::filament_present(const uint8_t extruder) {
runout.filament_present(extruder); // calls response.filament_present(extruder)
}
#if HAS_FILAMENT_RUNOUT_DISTANCE
float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM;
volatile float RunoutResponseDelayed::runout_mm_countdown[EXTRUDERS];

37
Marlin/src/feature/runout.h

@ -43,11 +43,29 @@
//#define FILAMENT_RUNOUT_SENSOR_DEBUG
#ifndef FILAMENT_RUNOUT_THRESHOLD
#define FILAMENT_RUNOUT_THRESHOLD 10
#define FILAMENT_RUNOUT_THRESHOLD 5
#endif
void event_filament_runout();
template<class RESPONSE_T, class SENSOR_T>
class TFilamentMonitor;
class FilamentSensorEncoder;
class FilamentSensorSwitch;
class RunoutResponseDelayed;
class RunoutResponseDebounced;
/********************************* TEMPLATE SPECIALIZATION *********************************/
typedef TFilamentMonitor<
TERN(HAS_FILAMENT_RUNOUT_DISTANCE, RunoutResponseDelayed, RunoutResponseDebounced),
TERN(FILAMENT_MOTION_SENSOR, FilamentSensorEncoder, FilamentSensorSwitch)
> FilamentMonitor;
extern FilamentMonitor runout;
/*******************************************************************************************/
class FilamentMonitorBase {
public:
static bool enabled, filament_ran_out;
@ -121,7 +139,13 @@ class TFilamentMonitor : public FilamentMonitorBase {
class FilamentSensorBase {
protected:
static void filament_present(const uint8_t extruder);
/**
* Called by FilamentSensorSwitch::run when filament is detected.
* Called by FilamentSensorEncoder::block_completed when motion is detected.
*/
static inline void filament_present(const uint8_t extruder) {
runout.filament_present(extruder); // ...which calls response.filament_present(extruder)
}
public:
static inline void setup() {
@ -311,12 +335,3 @@ class FilamentSensorBase {
};
#endif // !HAS_FILAMENT_RUNOUT_DISTANCE
/********************************* TEMPLATE SPECIALIZATION *********************************/
typedef TFilamentMonitor<
TERN(HAS_FILAMENT_RUNOUT_DISTANCE, RunoutResponseDelayed, RunoutResponseDebounced),
TERN(FILAMENT_MOTION_SENSOR, FilamentSensorEncoder, FilamentSensorSwitch)
> FilamentMonitor;
extern FilamentMonitor runout;

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save