Browse Source

Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bf2_granty_fix_15017

Scott Lahteine 6 years ago
parent
commit
09ee5a5da1
100 changed files with 8872 additions and 525 deletions
  1. 4
    4
      .circleci/config.yml
  2. 8
    1
      Marlin/Configuration.h
  3. 99
    28
      Marlin/Configuration_adv.h
  4. 20
    18
      Marlin/Makefile
  5. 1
    0
      Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h
  6. 1
    1
      Marlin/src/HAL/HAL_DUE/fastio_Due.h
  7. 6
    6
      Marlin/src/HAL/HAL_DUE/usb/compiler.h
  8. 4
    4
      Marlin/src/HAL/HAL_LINUX/include/serial.h
  9. 31
    7
      Marlin/src/HAL/HAL_LPC1768/usb_serial.cpp
  10. 2
    2
      Marlin/src/HAL/HAL_SAMD51/Servo_SAMD51.cpp
  11. 1
    0
      Marlin/src/HAL/HAL_SAMD51/fastio_SAMD51.h
  12. 1
    1
      Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h
  13. 14
    9
      Marlin/src/HAL/HAL_STM32/HAL_spi_STM32.cpp
  14. 1
    1
      Marlin/src/HAL/HAL_STM32/fastio_STM32.h
  15. 1
    1
      Marlin/src/HAL/HAL_STM32/pinsDebug_STM32duino.h
  16. 1
    1
      Marlin/src/HAL/HAL_STM32F1/HAL_spi_STM32F1.cpp
  17. 741
    0
      Marlin/src/HAL/HAL_STM32F1/SPI.cpp
  18. 409
    0
      Marlin/src/HAL/HAL_STM32F1/SPI.h
  19. 2
    2
      Marlin/src/HAL/HAL_STM32F1/fastio_STM32F1.h
  20. 10
    26
      Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp
  21. 21
    37
      Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/HAL_timers_STM32F4.cpp
  22. 3
    2
      Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/HAL_timers_STM32F7.cpp
  23. 0
    1
      Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp
  24. 3
    1
      Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.cpp
  25. 28
    11
      Marlin/src/Marlin.cpp
  26. 1
    0
      Marlin/src/Marlin.h
  27. 21
    19
      Marlin/src/core/boards.h
  28. 5
    3
      Marlin/src/core/drivers.h
  29. 6
    6
      Marlin/src/core/macros.h
  30. 2
    2
      Marlin/src/core/serial.h
  31. 5
    7
      Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
  32. 23
    16
      Marlin/src/feature/controllerfan.cpp
  33. 1
    1
      Marlin/src/feature/leds/leds.cpp
  34. 5
    3
      Marlin/src/feature/leds/pca9632.cpp
  35. 2
    1
      Marlin/src/feature/leds/pca9632.h
  36. 15
    2
      Marlin/src/feature/pause.cpp
  37. 10
    10
      Marlin/src/feature/power.cpp
  38. 19
    1
      Marlin/src/feature/power_loss_recovery.h
  39. 7
    0
      Marlin/src/feature/prusa_MMU2/mmu2.cpp
  40. 2
    0
      Marlin/src/feature/runout.h
  41. 1
    1
      Marlin/src/gcode/calibrate/G33.cpp
  42. 1
    1
      Marlin/src/gcode/calibrate/G34_M422.cpp
  43. 7
    0
      Marlin/src/gcode/config/M43.cpp
  44. 17
    10
      Marlin/src/gcode/control/M17_M18_M84.cpp
  45. 1
    1
      Marlin/src/gcode/eeprom/M500-M504.cpp
  46. 4
    0
      Marlin/src/gcode/gcode.cpp
  47. 5
    0
      Marlin/src/gcode/gcode.h
  48. 40
    0
      Marlin/src/gcode/host/M16.cpp
  49. 3
    0
      Marlin/src/gcode/lcd/M0_M1.cpp
  50. 3
    0
      Marlin/src/gcode/parser.cpp
  51. 17
    59
      Marlin/src/inc/Conditionals_LCD.h
  52. 3
    0
      Marlin/src/inc/Conditionals_adv.h
  53. 38
    2
      Marlin/src/inc/Conditionals_post.h
  54. 1
    0
      Marlin/src/inc/SanityCheck.h
  55. 1
    1
      Marlin/src/inc/Version.h
  56. 1
    1
      Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp
  57. 91
    91
      Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp
  58. 5
    1
      Marlin/src/lcd/dogm/HAL_LCD_com_defines.h
  59. 397
    2
      Marlin/src/lcd/dogm/dogm_Bootscreen.h
  60. 6
    6
      Marlin/src/lcd/dogm/dogm_Statusscreen.h
  61. 7
    11
      Marlin/src/lcd/dogm/lcdprint_u8g.cpp
  62. 12
    29
      Marlin/src/lcd/dogm/status_screen_DOGM.cpp
  63. 74
    74
      Marlin/src/lcd/dogm/ultralcd_DOGM.cpp
  64. 560
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.cpp
  65. 106
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.h
  66. 63
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.cpp
  67. 48
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.h
  68. 53
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/compat.h
  69. 97
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/config.h
  70. 674
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/LICENSE.txt
  71. 28
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/README.md
  72. 183
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/boards.h
  73. 1174
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.cpp
  74. 258
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.h
  75. 411
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/constants.h
  76. 118
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/display_list.h
  77. 40
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/ftdi_basic.h
  78. 150
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft800.h
  79. 185
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft810.h
  80. 128
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/resolutions.h
  81. 178
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.cpp
  82. 128
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.h
  83. 222
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/compat.h
  84. 49
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/bitmap_info.h
  85. 29
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.cpp
  86. 347
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.h
  87. 176
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.cpp
  88. 69
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.h
  89. 230
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.cpp
  90. 74
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.h
  91. 45
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/ftdi_extended.h
  92. 98
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/grid_layout.h
  93. 96
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/polygon.h
  94. 44
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/rgb_t.h
  95. 106
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.cpp
  96. 215
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.h
  97. 38
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_list.h
  98. 111
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.cpp
  99. 70
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.h
  100. 0
    0
      Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/text_box.cpp

+ 4
- 4
.circleci/config.yml View File

@@ -242,12 +242,12 @@ jobs:
242 242
             echo testing STM32F1 targets...
243 243
             export TEST_PLATFORM="-e STM32F1"
244 244
             restore_configs
245
-            echo use_example_configs STM32F10
246
-            use_example_configs STM32F10
245
+            echo use_example_configs STM32/STM32F10
246
+            use_example_configs STM32/STM32F10
247 247
             build_marlin_pio ./ ${TEST_PLATFORM}
248 248
             restore_configs
249
-            echo use_example_configs stm32f103ret6
250
-            use_example_configs stm32f103ret6
249
+            echo use_example_configs STM32/stm32f103ret6
250
+            use_example_configs STM32/stm32f103ret6
251 251
             build_marlin_pio ./ ${TEST_PLATFORM}
252 252
             restore_configs
253 253
 

+ 8
- 1
Marlin/Configuration.h View File

@@ -359,6 +359,7 @@
359 359
  *    -1 : thermocouple with AD595
360 360
  *     0 : not used
361 361
  *     1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
362
+ *   331 : (3.3V scaled thermistor 1 table)
362 363
  *     2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
363 364
  *     3 : Mendel-parts thermistor (4.7k pullup)
364 365
  *     4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
@@ -402,7 +403,7 @@
402 403
  *   998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below.
403 404
  *   999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below.
404 405
  *
405
- * :{ '0':"Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '501':"100K Zonestar (Tronxy X3A)", '512':"100k RPW-Ultra hotend thermistor", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950  1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '18':"ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327" '20':"Pt100 (Ultimainboard V2.x)", '201':"Pt100 (Overlord)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '61':"100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup", '66':"Dyze Design 4.7M High Temperature thermistor", '67':"Slice Engineering 450C High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-4':"Thermocouple + AD8495", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595", '998':"Dummy 1", '999':"Dummy 2", '1000':"Custom thermistor params" }
406
+ * :{ '0':"Not used", '1':"100k / 4.7k - EPCOS", '331':"(3.3V thermistor 1)", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '501':"100K Zonestar (Tronxy X3A)", '512':"100k RPW-Ultra hotend thermistor", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950  1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '18':"ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327" '20':"Pt100 (Ultimainboard V2.x)", '201':"Pt100 (Overlord)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '61':"100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup", '66':"Dyze Design 4.7M High Temperature thermistor", '67':"Slice Engineering 450C High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-4':"Thermocouple + AD8495", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595", '998':"Dummy 1", '999':"Dummy 2", '1000':"Custom thermistor params" }
406 407
  */
407 408
 #define TEMP_SENSOR_0 1
408 409
 #define TEMP_SENSOR_1 0
@@ -2034,6 +2035,12 @@
2034 2035
 //#define MALYAN_LCD
2035 2036
 
2036 2037
 //
2038
+// LulzBot Color Touch UI for FTDI EVE (FT800/FT810) displays
2039
+// See Configuration_adv.h for all configuration options.
2040
+//
2041
+//#define LULZBOT_TOUCH_UI
2042
+
2043
+//
2037 2044
 // Third-party or vendor-customized controller interfaces.
2038 2045
 // Sources should be installed in 'src/lcd/extensible_ui'.
2039 2046
 //

+ 99
- 28
Marlin/Configuration_adv.h View File

@@ -279,9 +279,10 @@
279 279
  */
280 280
 //#define USE_CONTROLLER_FAN
281 281
 #if ENABLED(USE_CONTROLLER_FAN)
282
-  //#define CONTROLLER_FAN_PIN -1        // Set a custom pin for the controller fan
283
-  #define CONTROLLERFAN_SECS 60          // Duration in seconds for the fan to run after all motors are disabled
284
-  #define CONTROLLERFAN_SPEED 255        // 255 == full speed
282
+  //#define CONTROLLER_FAN_PIN -1           // Set a custom pin for the controller fan
283
+  #define CONTROLLERFAN_SECS 60             // Duration in seconds for the fan to run after all motors are disabled
284
+  #define CONTROLLERFAN_SPEED 255           // 255 == full speed
285
+  //#define CONTROLLERFAN_SPEED_Z_ONLY 127  // Reduce noise on machines that keep Z enabled
285 286
 #endif
286 287
 
287 288
 // When first starting the main fan, run it at full speed for the
@@ -657,10 +658,10 @@
657 658
   #endif
658 659
 #endif
659 660
 
660
-// @section extras
661
+// @section motion
661 662
 
662
-// minimum time in microseconds that a movement needs to take if the buffer is emptied.
663
-#define DEFAULT_MINSEGMENTTIME        20000
663
+// Minimum time that a segment needs to take if the buffer is emptied
664
+#define DEFAULT_MINSEGMENTTIME        20000   // (ms)
664 665
 
665 666
 // If defined the movements slow down when the look ahead buffer is only half full
666 667
 #define SLOWDOWN
@@ -850,11 +851,35 @@
850 851
   #define FEEDRATE_CHANGE_BEEP_FREQUENCY 440
851 852
 #endif
852 853
 
853
-// Include a page of printer information in the LCD Main Menu
854
-//#define LCD_INFO_MENU
855
-#if ENABLED(LCD_INFO_MENU)
856
-  //#define LCD_PRINTER_INFO_IS_BOOTSCREEN // Show bootscreen(s) instead of Printer Info pages
857
-#endif
854
+#if HAS_LCD_MENU
855
+
856
+  // Include a page of printer information in the LCD Main Menu
857
+  //#define LCD_INFO_MENU
858
+  #if ENABLED(LCD_INFO_MENU)
859
+    //#define LCD_PRINTER_INFO_IS_BOOTSCREEN // Show bootscreen(s) instead of Printer Info pages
860
+  #endif
861
+
862
+  // BACK menu items keep the highlight at the top
863
+  //#define TURBO_BACK_MENU_ITEM
864
+
865
+  /**
866
+   * LED Control Menu
867
+   * Add LED Control to the LCD menu
868
+   */
869
+  //#define LED_CONTROL_MENU
870
+  #if ENABLED(LED_CONTROL_MENU)
871
+    #define LED_COLOR_PRESETS                 // Enable the Preset Color menu option
872
+    #if ENABLED(LED_COLOR_PRESETS)
873
+      #define LED_USER_PRESET_RED        255  // User defined RED value
874
+      #define LED_USER_PRESET_GREEN      128  // User defined GREEN value
875
+      #define LED_USER_PRESET_BLUE         0  // User defined BLUE value
876
+      #define LED_USER_PRESET_WHITE      255  // User defined WHITE value
877
+      #define LED_USER_PRESET_BRIGHTNESS 255  // User defined intensity
878
+      //#define LED_USER_PRESET_STARTUP       // Have the printer display the user preset color on startup
879
+    #endif
880
+  #endif
881
+
882
+#endif // HAS_LCD_MENU
858 883
 
859 884
 // Scroll a longer status message into view
860 885
 //#define STATUS_MESSAGE_SCROLLING
@@ -879,23 +904,6 @@
879 904
   #endif
880 905
 #endif
881 906
 
882
-/**
883
- * LED Control Menu
884
- * Enable this feature to add LED Control to the LCD menu
885
- */
886
-//#define LED_CONTROL_MENU
887
-#if ENABLED(LED_CONTROL_MENU)
888
-  #define LED_COLOR_PRESETS                 // Enable the Preset Color menu option
889
-  #if ENABLED(LED_COLOR_PRESETS)
890
-    #define LED_USER_PRESET_RED        255  // User defined RED value
891
-    #define LED_USER_PRESET_GREEN      128  // User defined GREEN value
892
-    #define LED_USER_PRESET_BLUE         0  // User defined BLUE value
893
-    #define LED_USER_PRESET_WHITE      255  // User defined WHITE value
894
-    #define LED_USER_PRESET_BRIGHTNESS 255  // User defined intensity
895
-    //#define LED_USER_PRESET_STARTUP       // Have the printer display the user preset color on startup
896
-  #endif
897
-#endif // LED_CONTROL_MENU
898
-
899 907
 #if ENABLED(SDSUPPORT)
900 908
 
901 909
   // Some RAMPS and other boards don't detect when an SD card is inserted. You can work
@@ -930,6 +938,7 @@
930 938
   #if ENABLED(POWER_LOSS_RECOVERY)
931 939
     //#define POWER_LOSS_PIN         44 // Pin to detect power loss
932 940
     //#define POWER_LOSS_STATE     HIGH // State of pin indicating power loss
941
+    //#define POWER_LOSS_PULL           // Set pullup / pulldown as appropriate
933 942
     //#define POWER_LOSS_PURGE_LEN   20 // (mm) Length of filament to purge on resume
934 943
     //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power.
935 944
 
@@ -1134,6 +1143,7 @@
1134 1143
   //#define STATUS_FAN_FRAMES 3       // :[0,1,2,3,4] Number of fan animation frames
1135 1144
   //#define STATUS_HEAT_PERCENT       // Show heating in a progress bar
1136 1145
   //#define BOOT_MARLIN_LOGO_SMALL    // Show a smaller Marlin logo on the Boot Screen (saving 399 bytes of flash)
1146
+  //#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~‭3260 (or ~940) bytes of PROGMEM.
1137 1147
 
1138 1148
   // Frivolous Game Options
1139 1149
   //#define MARLIN_BRICKOUT
@@ -1143,6 +1153,53 @@
1143 1153
 
1144 1154
 #endif // HAS_GRAPHICAL_LCD
1145 1155
 
1156
+//
1157
+// Lulzbot Touch UI
1158
+//
1159
+#if ENABLED(LULZBOT_TOUCH_UI)
1160
+  // Display board used
1161
+  //#define LCD_FTDI_VM800B35A        // FTDI 3.5" with FT800 (320x240)
1162
+  //#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272)
1163
+  //#define LCD_HAOYU_FT800CB         // Haoyu with 4.3" or 5" (480x272)
1164
+  //#define LCD_HAOYU_FT810CB         // Haoyu with 5" (800x480)
1165
+  //#define LCD_ALEPHOBJECTS_CLCD_UI  // Aleph Objects Color LCD UI
1166
+
1167
+  // Correct the resolution if not using the stock TFT panel.
1168
+  //#define TOUCH_UI_320x240
1169
+  //#define TOUCH_UI_480x272
1170
+  //#define TOUCH_UI_800x480
1171
+
1172
+  // Mappings for boards with a standard RepRapDiscount Display connector
1173
+  //#define AO_EXP1_PINMAP    // AlephObjects CLCD UI EXP1 mapping
1174
+  //#define AO_EXP2_PINMAP    // AlephObjects CLCD UI EXP2 mapping
1175
+  //#define CR10_TFT_PINMAP   // Rudolph Riedel's CR10 pin mapping
1176
+  //#define OTHER_PIN_LAYOUT  // Define pins manually below
1177
+  #if ENABLED(OTHER_PIN_LAYOUT)
1178
+    // The pins for CS and MOD_RESET (PD) must be chosen.
1179
+    #define CLCD_MOD_RESET  9
1180
+    #define CLCD_SPI_CS    10
1181
+
1182
+    // If using software SPI, specify pins for SCLK, MOSI, MISO
1183
+    //#define CLCD_USE_SOFT_SPI
1184
+    #if ENABLED(CLCD_USE_SOFT_SPI)
1185
+      #define CLCD_SOFT_SPI_MOSI 11
1186
+      #define CLCD_SOFT_SPI_MISO 12
1187
+      #define CLCD_SOFT_SPI_SCLK 13
1188
+    #endif
1189
+  #endif
1190
+
1191
+  // Display Orientation. An inverted (i.e. upside-down) display
1192
+  // is supported on the FT800. The FT810 and beyond also support
1193
+  // portrait and mirrored orientations.
1194
+  //#define TOUCH_UI_INVERTED
1195
+  //#define TOUCH_UI_PORTRAIT
1196
+  //#define TOUCH_UI_MIRRORED
1197
+
1198
+  // Use a numeric passcode for "Screen lock" keypad.
1199
+  // (recommended for smaller displays)
1200
+  //#define TOUCH_UI_PASSCODE
1201
+#endif
1202
+
1146 1203
 // @section safety
1147 1204
 
1148 1205
 /**
@@ -2243,6 +2300,13 @@
2243 2300
 #define EXTENDED_CAPABILITIES_REPORT
2244 2301
 
2245 2302
 /**
2303
+ * Expected Printer Check
2304
+ * Add the M16 G-code to compare a string to the MACHINE_NAME.
2305
+ * M16 with a non-matching string causes the printer to halt.
2306
+ */
2307
+//#define EXPECTED_PRINTER_CHECK
2308
+
2309
+/**
2246 2310
  * Disable all Volumetric extrusion options
2247 2311
  */
2248 2312
 //#define NO_VOLUMETRICS
@@ -2297,6 +2361,13 @@
2297 2361
 #endif
2298 2362
 
2299 2363
 /**
2364
+ * Startup commands
2365
+ *
2366
+ * Execute certain G-code commands immediately after power-on.
2367
+ */
2368
+//#define STARTUP_COMMANDS "M17 Z"
2369
+
2370
+/**
2300 2371
  * G-code Macros
2301 2372
  *
2302 2373
  * Add G-codes M810-M819 to define and run G-code macros.

+ 20
- 18
Marlin/Makefile View File

@@ -281,42 +281,44 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1205)
281 281
 else ifeq ($(HARDWARE_MOTHERBOARD),1300)
282 282
 # Cartesio CN Controls V12
283 283
 else ifeq ($(HARDWARE_MOTHERBOARD),1301)
284
-# Cheaptronic v1.0
284
+# Cartesio CN Controls V15
285 285
 else ifeq ($(HARDWARE_MOTHERBOARD),1302)
286
-# Cheaptronic v2.0
286
+# Cheaptronic v1.0
287 287
 else ifeq ($(HARDWARE_MOTHERBOARD),1303)
288
-# Makerbot Mightyboard Revision E
288
+# Cheaptronic v2.0
289 289
 else ifeq ($(HARDWARE_MOTHERBOARD),1304)
290
-# Megatronics
290
+# Makerbot Mightyboard Revision E
291 291
 else ifeq ($(HARDWARE_MOTHERBOARD),1305)
292
-# Megatronics v2.0
292
+# Megatronics
293 293
 else ifeq ($(HARDWARE_MOTHERBOARD),1306)
294
-# Megatronics v3.0
294
+# Megatronics v2.0
295 295
 else ifeq ($(HARDWARE_MOTHERBOARD),1307)
296
-# Megatronics v3.1
296
+# Megatronics v3.0
297 297
 else ifeq ($(HARDWARE_MOTHERBOARD),1308)
298
-# Megatronics v3.2
298
+# Megatronics v3.1
299 299
 else ifeq ($(HARDWARE_MOTHERBOARD),1309)
300
-# Elefu Ra Board (v3)
300
+# Megatronics v3.2
301 301
 else ifeq ($(HARDWARE_MOTHERBOARD),1310)
302
-# Leapfrog
302
+# Elefu Ra Board (v3)
303 303
 else ifeq ($(HARDWARE_MOTHERBOARD),1311)
304
-# Mega controller
304
+# Leapfrog
305 305
 else ifeq ($(HARDWARE_MOTHERBOARD),1312)
306
-# Geeetech GT2560 Rev B for Mecreator2
306
+# Mega controller
307 307
 else ifeq ($(HARDWARE_MOTHERBOARD),1313)
308
-# Geeetech GT2560 Rev. A
308
+# Geeetech GT2560 Rev B for Mecreator2
309 309
 else ifeq ($(HARDWARE_MOTHERBOARD),1314)
310
-# Geeetech GT2560 Rev. A+ (with auto level probe)
310
+# Geeetech GT2560 Rev. A
311 311
 else ifeq ($(HARDWARE_MOTHERBOARD),1315)
312
-# Geeetech GT2560 Rev B for A10(M/D)
312
+# Geeetech GT2560 Rev. A+ (with auto level probe)
313 313
 else ifeq ($(HARDWARE_MOTHERBOARD),1316)
314
-# Geeetech GT2560 Rev B for A20(M/D)
314
+# Geeetech GT2560 Rev B for A10(M/D)
315 315
 else ifeq ($(HARDWARE_MOTHERBOARD),1317)
316
-# Einstart retrofit
316
+# Geeetech GT2560 Rev B for A20(M/D)
317 317
 else ifeq ($(HARDWARE_MOTHERBOARD),1318)
318
-# Wanhao 0ne+ i3 Mini
318
+# Einstart retrofit
319 319
 else ifeq ($(HARDWARE_MOTHERBOARD),1319)
320
+# Wanhao 0ne+ i3 Mini
321
+else ifeq ($(HARDWARE_MOTHERBOARD),1320)
320 322
 
321 323
 #
322 324
 # ATmega1281, ATmega2561

+ 1
- 0
Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h View File

@@ -23,6 +23,7 @@
23 23
 
24 24
 #include "../../../inc/MarlinConfigPre.h"
25 25
 #include "../../shared/Marduino.h"
26
+#include <U8glib.h>
26 27
 
27 28
 void u8g_SetPIOutput_DUE(u8g_t *u8g, uint8_t pin_index);
28 29
 void u8g_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level);

+ 1
- 1
Marlin/src/HAL/HAL_DUE/fastio_Due.h View File

@@ -70,7 +70,7 @@
70 70
   const uint32_t mask = MASK(DIO ## IO ## _PIN); \
71 71
   if (V) port->PIO_SODR = mask; \
72 72
   else port->PIO_CODR = mask; \
73
-} while(0)
73
+}while(0)
74 74
 
75 75
 // Toggle a pin
76 76
 #define _TOGGLE(IO) _WRITE(IO, !READ(IO))

+ 6
- 6
Marlin/src/HAL/HAL_DUE/usb/compiler.h View File

@@ -112,7 +112,7 @@
112 112
  * \def unused
113 113
  * \brief Marking \a v as a unused parameter or value.
114 114
  */
115
-#define unused(v)          do { (void)(v); } while(0)
115
+#define unused(v)          do { (void)(v); }while(0)
116 116
 
117 117
 /**
118 118
  * \def barrier
@@ -169,7 +169,7 @@
169 169
  * heuristics and inline the function no matter how big it thinks it
170 170
  * becomes.
171 171
  */
172
-#if defined(__CC_ARM)
172
+#ifdef __CC_ARM
173 173
 #   define __always_inline   __forceinline
174 174
 #elif (defined __GNUC__)
175 175
 #ifdef __always_inline
@@ -187,7 +187,7 @@
187 187
  * This annotation instructs the compiler to ignore its inlining
188 188
  * heuristics and not inline the function.
189 189
  */
190
-#if defined(__CC_ARM)
190
+#ifdef __CC_ARM
191 191
 #   define __no_inline   __attribute__((noinline))
192 192
 #elif (defined __GNUC__)
193 193
 #	define __no_inline   __attribute__((__noinline__))
@@ -204,7 +204,7 @@
204 204
  *
205 205
  * \param expr  Expression to evaluate and supposed to be nonzero.
206 206
  */
207
-#if defined(_ASSERT_ENABLE_)
207
+#ifdef _ASSERT_ENABLE_
208 208
 #  if defined(TEST_SUITE_DEFINE_ASSERT_MACRO)
209 209
      // Assert() is defined in unit_test/suite.h
210 210
 #    include "unit_test/suite.h"
@@ -998,14 +998,14 @@ typedef U8                  Byte;       //!< 8-bit unsigned integer.
998 998
 #endif  // #ifndef __ASSEMBLY__
999 999
 
1000 1000
 
1001
-#if defined(__ICCARM__)
1001
+#ifdef __ICCARM__
1002 1002
 #define SHORTENUM           __packed
1003 1003
 #elif defined(__GNUC__)
1004 1004
 #define SHORTENUM           __attribute__((packed))
1005 1005
 #endif
1006 1006
 
1007 1007
 /* No operation */
1008
-#if defined(__ICCARM__)
1008
+#ifdef __ICCARM__
1009 1009
 #define nop()               __no_operation()
1010 1010
 #elif defined(__GNUC__)
1011 1011
 #define nop()               (__NOP())

+ 4
- 4
Marlin/src/HAL/HAL_LINUX/include/serial.h View File

@@ -142,10 +142,10 @@ public:
142 142
   void print_bin(uint32_t value, uint8_t num_digits) {
143 143
     uint32_t mask = 1 << (num_digits -1);
144 144
     for (uint8_t i = 0; i < num_digits; i++) {
145
-      if (!(i % 4) && i)    write(' ');
146
-      if (!(i % 16)  && i)  write(' ');
147
-      if (value & mask)     write('1');
148
-      else                  write('0');
145
+      if (!(i %  4) && i) write(' ');
146
+      if (!(i % 16) && i) write(' ');
147
+      if (value & mask)   write('1');
148
+      else                write('0');
149 149
       value <<= 1;
150 150
     }
151 151
   }

+ 31
- 7
Marlin/src/HAL/HAL_LPC1768/usb_serial.cpp View File

@@ -1,13 +1,37 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
1 23
 #ifdef TARGET_LPC1768
24
+
2 25
 #include "../../inc/MarlinConfigPre.h"
3 26
 
4 27
 #if ENABLED(EMERGENCY_PARSER)
5
-  #include "../../feature/emergency_parser.h"
6
-  EmergencyParser::State emergency_state;
7
-  bool CDC_RecvCallback(const char buffer) {
8
-    emergency_parser.update(emergency_state, buffer);
9
-    return true;
10
-  }
11
-#endif // ENABLED(EMERGENCY_PARSER)
12 28
 
29
+#include "../../feature/emergency_parser.h"
30
+EmergencyParser::State emergency_state;
31
+bool CDC_RecvCallback(const char buffer) {
32
+  emergency_parser.update(emergency_state, buffer);
33
+  return true;
34
+}
35
+
36
+#endif // EMERGENCY_PARSER
13 37
 #endif // TARGET_LPC1768

+ 2
- 2
Marlin/src/HAL/HAL_SAMD51/Servo_SAMD51.cpp View File

@@ -115,12 +115,12 @@ HAL_SERVO_TIMER_ISR() {
115 115
       tc->COUNT16.CC[tcChannel].reg = (uint16_t)(tcCounterValue - 4UL);               // at least REFRESH_INTERVAL has elapsed
116 116
   }
117 117
   if (tcChannel == 0) {
118
-    SYNC(tc->COUNT16.SYNCBUSY.bit.CC0); 
118
+    SYNC(tc->COUNT16.SYNCBUSY.bit.CC0);
119 119
     // Clear the interrupt
120 120
     tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0;
121 121
   }
122 122
   else {
123
-    SYNC(tc->COUNT16.SYNCBUSY.bit.CC1); 
123
+    SYNC(tc->COUNT16.SYNCBUSY.bit.CC1);
124 124
     // Clear the interrupt
125 125
     tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC1;
126 126
   }

+ 1
- 0
Marlin/src/HAL/HAL_SAMD51/fastio_SAMD51.h View File

@@ -243,6 +243,7 @@
243 243
   #define DIO5_PIN    PIN_PC21
244 244
   #define DIO16_PIN   PIN_PC22
245 245
   #define DIO17_PIN   PIN_PC23
246
+  #define DIO88_PIN   PIN_PC24    // NEOPIXEL
246 247
   // PORTD
247 248
   #define DIO22_PIN   PIN_PD12
248 249
   #define DIO6_PIN    PIN_PD20

+ 1
- 1
Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h View File

@@ -32,7 +32,7 @@
32 32
 #endif
33 33
 
34 34
 #if ENABLED(EMERGENCY_PARSER)
35
-  #error "EMERGENCY_PARSER is not yet implemented for STM32F4. Disable EMERGENCY_PARSER to continue."
35
+  #error "EMERGENCY_PARSER is not yet implemented for SAMD51. Disable EMERGENCY_PARSER to continue."
36 36
 #endif
37 37
 
38 38
 #if ENABLED(SDIO_SUPPORT)

+ 14
- 9
Marlin/src/HAL/HAL_STM32/HAL_spi_STM32.cpp View File

@@ -22,7 +22,6 @@
22 22
  */
23 23
 #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
24 24
 
25
-
26 25
 #include "../../inc/MarlinConfig.h"
27 26
 
28 27
 #include <SPI.h>
@@ -73,16 +72,22 @@ void spiInit(uint8_t spiRate) {
73 72
   // Use datarates Marlin uses
74 73
   uint32_t clock;
75 74
   switch (spiRate) {
76
-  case SPI_FULL_SPEED:    clock = 20000000; break; // 13.9mhz=20000000  6.75mhz=10000000  3.38mhz=5000000  .833mhz=1000000
77
-  case SPI_HALF_SPEED:    clock =  5000000; break;
78
-  case SPI_QUARTER_SPEED: clock =  2500000; break;
79
-  case SPI_EIGHTH_SPEED:  clock =  1250000; break;
80
-  case SPI_SPEED_5:       clock =   625000; break;
81
-  case SPI_SPEED_6:       clock =   300000; break;
82
-  default:
83
-    clock = 4000000; // Default from the SPI library
75
+    case SPI_FULL_SPEED:    clock = 20000000; break; // 13.9mhz=20000000  6.75mhz=10000000  3.38mhz=5000000  .833mhz=1000000
76
+    case SPI_HALF_SPEED:    clock =  5000000; break;
77
+    case SPI_QUARTER_SPEED: clock =  2500000; break;
78
+    case SPI_EIGHTH_SPEED:  clock =  1250000; break;
79
+    case SPI_SPEED_5:       clock =   625000; break;
80
+    case SPI_SPEED_6:       clock =   300000; break;
81
+    default:
82
+      clock = 4000000; // Default from the SPI library
84 83
   }
85 84
   spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
85
+  #if defined(MISO_PIN) && defined(SDSS) && defined(MOSI_PIN) && defined(SCK_PIN)
86
+    SPI.setMISO(MISO_PIN);
87
+    SPI.setSSEL(SDSS);
88
+    SPI.setMOSI(MOSI_PIN);
89
+    SPI.setSCLK(SCK_PIN);
90
+  #endif
86 91
   SPI.begin();
87 92
 }
88 93
 

+ 1
- 1
Marlin/src/HAL/HAL_STM32/fastio_STM32.h View File

@@ -53,7 +53,7 @@ void FastIO_init(); // Must be called before using fast io macros
53 53
   #define _WRITE(IO, V) do { \
54 54
     if (V) FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO])) ; \
55 55
     else   FastIOPortMap[STM_PORT(digitalPin[IO])]->BRR  = _BV32(STM_PIN(digitalPin[IO])) ; \
56
-  } while(0)
56
+  }while(0)
57 57
 #else
58 58
   #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO]) + (V ? 0 : 16)))
59 59
 #endif

+ 1
- 1
Marlin/src/HAL/HAL_STM32/pinsDebug_STM32duino.h View File

@@ -189,7 +189,7 @@ void port_print(const pin_t Ard_num) {
189 189
   for (Index = 0; Index < NUMBER_PINS_TOTAL; Index++)
190 190
     if (Ard_num == GET_PIN_MAP_PIN_M43(Index)) break;
191 191
 
192
-  char * const ppa = pin_xref[Index].Port_pin_alpha;
192
+  const char * ppa = pin_xref[Index].Port_pin_alpha;
193 193
   sprintf_P(buffer, PSTR("%s"), ppa);
194 194
   SERIAL_ECHO(buffer);
195 195
   if (ppa[3] == '\0') SERIAL_CHAR(' ');

+ 1
- 1
Marlin/src/HAL/HAL_STM32F1/HAL_spi_STM32F1.cpp View File

@@ -33,7 +33,7 @@
33 33
 #ifdef __STM32F1__
34 34
 
35 35
 #include "../../inc/MarlinConfig.h"
36
-#include <SPI.h>
36
+#include "SPI.h"
37 37
 
38 38
 // ------------------------
39 39
 // Public functions

+ 741
- 0
Marlin/src/HAL/HAL_STM32F1/SPI.cpp View File

@@ -0,0 +1,741 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+
27
+/**
28
+ * @author Marti Bolivar <mbolivar@leaflabs.com>
29
+ * @brief Wirish SPI implementation.
30
+ */
31
+
32
+#ifdef __STM32F1__
33
+
34
+#include "SPI.h"
35
+
36
+#include <libmaple/timer.h>
37
+#include <libmaple/util.h>
38
+#include <libmaple/rcc.h>
39
+
40
+#include <boards.h>
41
+#include <wirish.h>
42
+
43
+/** Time in ms for DMA receive timeout */
44
+#define DMA_TIMEOUT 100
45
+
46
+#if CYCLES_PER_MICROSECOND != 72
47
+  #warning "Unexpected clock speed; SPI frequency calculation will be incorrect"
48
+#endif
49
+
50
+struct spi_pins {
51
+  uint8_t nss;
52
+  uint8_t sck;
53
+  uint8_t miso;
54
+  uint8_t mosi;
55
+};
56
+
57
+static const spi_pins* dev_to_spi_pins(spi_dev *dev);
58
+static void configure_gpios(spi_dev *dev, bool as_master);
59
+static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq);
60
+
61
+#if (BOARD_NR_SPI >= 3) && !defined(STM32_HIGH_DENSITY)
62
+  #error "The SPI library is misconfigured: 3 SPI ports only available on high density STM32 devices"
63
+#endif
64
+
65
+static const spi_pins board_spi_pins[] __FLASH__ = {
66
+  #if BOARD_NR_SPI >= 1
67
+  { BOARD_SPI1_NSS_PIN,
68
+    BOARD_SPI1_SCK_PIN,
69
+    BOARD_SPI1_MISO_PIN,
70
+    BOARD_SPI1_MOSI_PIN },
71
+  #endif
72
+  #if BOARD_NR_SPI >= 2
73
+  { BOARD_SPI2_NSS_PIN,
74
+    BOARD_SPI2_SCK_PIN,
75
+    BOARD_SPI2_MISO_PIN,
76
+    BOARD_SPI2_MOSI_PIN },
77
+  #endif
78
+  #if BOARD_NR_SPI >= 3
79
+  { BOARD_SPI3_NSS_PIN,
80
+    BOARD_SPI3_SCK_PIN,
81
+    BOARD_SPI3_MISO_PIN,
82
+    BOARD_SPI3_MOSI_PIN },
83
+  #endif
84
+};
85
+
86
+#if BOARD_NR_SPI >= 1
87
+  static void (*_spi1_this);
88
+#endif
89
+#if BOARD_NR_SPI >= 2
90
+  static void (*_spi2_this);
91
+#endif
92
+#if BOARD_NR_SPI >= 3
93
+  static void (*_spi3_this);
94
+#endif
95
+
96
+/**
97
+ * Constructor
98
+ */
99
+SPIClass::SPIClass(uint32_t spi_num) {
100
+  _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
101
+
102
+  switch (spi_num) {
103
+    #if BOARD_NR_SPI >= 1
104
+      case 1:
105
+        _currentSetting->spi_d = SPI1;
106
+        _spi1_this = (void*)this;
107
+        break;
108
+    #endif
109
+    #if BOARD_NR_SPI >= 2
110
+      case 2:
111
+        _currentSetting->spi_d = SPI2;
112
+        _spi2_this = (void*)this;
113
+        break;
114
+    #endif
115
+    #if BOARD_NR_SPI >= 3
116
+      case 3:
117
+        _currentSetting->spi_d = SPI3;
118
+        _spi3_this = (void*)this;
119
+        break;
120
+    #endif
121
+    default: ASSERT(0);
122
+  }
123
+
124
+  // Init things specific to each SPI device
125
+  // clock divider setup is a bit of hack, and needs to be improved at a later date.
126
+  #if BOARD_NR_SPI >= 1
127
+    _settings[0].spi_d = SPI1;
128
+    _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
129
+    _settings[0].spiDmaDev = DMA1;
130
+    _settings[0].spiTxDmaChannel = DMA_CH3;
131
+    _settings[0].spiRxDmaChannel = DMA_CH2;
132
+  #endif
133
+  #if BOARD_NR_SPI >= 2
134
+    _settings[1].spi_d = SPI2;
135
+    _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
136
+    _settings[1].spiDmaDev = DMA1;
137
+    _settings[1].spiTxDmaChannel = DMA_CH5;
138
+    _settings[1].spiRxDmaChannel = DMA_CH4;
139
+  #endif
140
+  #if BOARD_NR_SPI >= 3
141
+    _settings[2].spi_d = SPI3;
142
+    _settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock);
143
+    _settings[2].spiDmaDev = DMA2;
144
+    _settings[2].spiTxDmaChannel = DMA_CH2;
145
+    _settings[2].spiRxDmaChannel = DMA_CH1;
146
+  #endif
147
+
148
+  // added for DMA callbacks.
149
+  _currentSetting->state = SPI_STATE_IDLE;
150
+}
151
+
152
+/*
153
+ * Set up/tear down
154
+ */
155
+void SPIClass::updateSettings() {
156
+  uint32_t flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS);
157
+  spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags);
158
+}
159
+
160
+void SPIClass::begin() {
161
+  spi_init(_currentSetting->spi_d);
162
+  configure_gpios(_currentSetting->spi_d, 1);
163
+  updateSettings();
164
+  // added for DMA callbacks.
165
+  _currentSetting->state = SPI_STATE_READY;
166
+}
167
+
168
+void SPIClass::beginSlave() {
169
+  spi_init(_currentSetting->spi_d);
170
+  configure_gpios(_currentSetting->spi_d, 0);
171
+  uint32_t flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize);
172
+  spi_slave_enable(_currentSetting->spi_d, (spi_mode)_currentSetting->dataMode, flags);
173
+  // added for DMA callbacks.
174
+  _currentSetting->state = SPI_STATE_READY;
175
+}
176
+
177
+void SPIClass::end() {
178
+  if (!spi_is_enabled(_currentSetting->spi_d))
179
+    return;
180
+
181
+  // Follows RM0008's sequence for disabling a SPI in master/slave
182
+  // full duplex mode.
183
+  while (spi_is_rx_nonempty(_currentSetting->spi_d)) {
184
+    // FIXME [0.1.0] remove this once you have an interrupt based driver
185
+    volatile uint16_t rx __attribute__((unused)) = spi_rx_reg(_currentSetting->spi_d);
186
+  }
187
+  while (!spi_is_tx_empty(_currentSetting->spi_d)) {};
188
+  while (spi_is_busy(_currentSetting->spi_d)) {};
189
+
190
+  spi_peripheral_disable(_currentSetting->spi_d);
191
+  // added for DMA callbacks.
192
+  // Need to add unsetting the callbacks for the DMA channels.
193
+  _currentSetting->state = SPI_STATE_IDLE;
194
+}
195
+
196
+/* Roger Clark added  3 functions */
197
+void SPIClass::setClockDivider(uint32_t clockDivider) {
198
+  _currentSetting->clockDivider = clockDivider;
199
+  uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR);
200
+  _currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR);
201
+}
202
+
203
+void SPIClass::setBitOrder(BitOrder bitOrder) {
204
+  _currentSetting->bitOrder = bitOrder;
205
+  uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST);
206
+  if (bitOrder == LSBFIRST) cr1 |= SPI_CR1_LSBFIRST;
207
+  _currentSetting->spi_d->regs->CR1 = cr1;
208
+}
209
+
210
+/*  Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly.
211
+* Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word.
212
+*
213
+*/
214
+void SPIClass::setDataSize(uint32_t datasize) {
215
+  _currentSetting->dataSize = datasize;
216
+  uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF);
217
+  uint8_t en = spi_is_enabled(_currentSetting->spi_d);
218
+  spi_peripheral_disable(_currentSetting->spi_d);
219
+  _currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en;
220
+}
221
+
222
+void SPIClass::setDataMode(uint8_t dataMode) {
223
+  /* Notes:
224
+  As far as I can tell, the AVR numbers for dataMode appear to match the numbers required by the STM32
225
+  From the AVR doc http://www.atmel.com/images/doc2585.pdf section 2.4
226
+  SPI Mode  CPOL  CPHA  Shift SCK-edge  Capture SCK-edge
227
+  0       0     0     Falling     Rising
228
+  1       0     1     Rising      Falling
229
+  2       1     0     Rising      Falling
230
+  3       1     1     Falling     Rising
231
+
232
+  On the STM32 it appears to be
233
+
234
+  bit 1 - CPOL : Clock polarity
235
+    (This bit should not be changed when communication is ongoing)
236
+    0 : CLK to 0 when idle
237
+    1 : CLK to 1 when idle
238
+
239
+  bit 0 - CPHA : Clock phase
240
+    (This bit should not be changed when communication is ongoing)
241
+    0 : The first clock transition is the first data capture edge
242
+    1 : The second clock transition is the first data capture edge
243
+
244
+  If someone finds this is not the case or sees a logic error with this let me know ;-)
245
+  */
246
+  _currentSetting->dataMode = dataMode;
247
+  uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA);
248
+  _currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA));
249
+}
250
+
251
+void SPIClass::beginTransaction(uint8_t pin, SPISettings settings) {
252
+  setBitOrder(settings.bitOrder);
253
+  setDataMode(settings.dataMode);
254
+  setDataSize(settings.dataSize);
255
+  setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
256
+  begin();
257
+}
258
+
259
+void SPIClass::beginTransactionSlave(SPISettings settings) {
260
+  setBitOrder(settings.bitOrder);
261
+  setDataMode(settings.dataMode);
262
+  setDataSize(settings.dataSize);
263
+  beginSlave();
264
+}
265
+
266
+void SPIClass::endTransaction() { }
267
+
268
+
269
+/*
270
+ * I/O
271
+ */
272
+
273
+uint16_t SPIClass::read() {
274
+  while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ;
275
+  return (uint16)spi_rx_reg(_currentSetting->spi_d);
276
+}
277
+
278
+void SPIClass::read(uint8_t *buf, uint32_t len) {
279
+  if (len == 0) return;
280
+  spi_rx_reg(_currentSetting->spi_d);   // clear the RX buffer in case a byte is waiting on it.
281
+  spi_reg_map * regs = _currentSetting->spi_d->regs;
282
+  // start sequence: write byte 0
283
+  regs->DR = 0x00FF;            // write the first byte
284
+  // main loop
285
+  while ( (--len) ) {
286
+    while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag
287
+    noInterrupts();    // go atomic level - avoid interrupts to surely get the previously received data
288
+    regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag.
289
+    while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register
290
+    *buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag.
291
+    interrupts();      // let systick do its job
292
+  }
293
+  // read remaining last byte
294
+  while ( !(regs->SR & SPI_SR_RXNE) ) {} // wait till data is available in the Rx register
295
+  *buf++ = (uint8)(regs->DR);  // read and store the received byte
296
+}
297
+
298
+void SPIClass::write(uint16_t data) {
299
+  /* Added for 16bit data Victor Perez. Roger Clark
300
+   * Improved speed by just directly writing the single byte to the SPI data reg and wait for completion,
301
+   * by taking the Tx code from transfer(byte)
302
+   * This almost doubles the speed of this function.
303
+   */
304
+  spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
305
+  while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
306
+  while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
307
+}
308
+
309
+void SPIClass::write16(uint16_t data) {
310
+  // Added by stevestrong: write two consecutive bytes in 8 bit mode (DFF=0)
311
+  spi_tx_reg(_currentSetting->spi_d, data>>8); // write high byte
312
+  while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // Wait until TXE=1
313
+  spi_tx_reg(_currentSetting->spi_d, data); // write low byte
314
+  while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // Wait until TXE=1
315
+  while (spi_is_busy(_currentSetting->spi_d) != 0); // wait until BSY=0
316
+}
317
+
318
+void SPIClass::write(uint16_t data, uint32_t n) {
319
+  // Added by stevstrong: Repeatedly send same data by the specified number of times
320
+  spi_reg_map * regs = _currentSetting->spi_d->regs;
321
+  while ( (n--)>0 ) {
322
+    regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
323
+    while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty
324
+  }
325
+  while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning
326
+}
327
+
328
+void SPIClass::write(const void *data, uint32_t length) {
329
+  spi_dev * spi_d = _currentSetting->spi_d;
330
+  spi_tx(spi_d, data, length); // data can be array of bytes or words
331
+  while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
332
+  while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
333
+}
334
+
335
+uint8_t SPIClass::transfer(uint8_t byte) const {
336
+  spi_dev * spi_d = _currentSetting->spi_d;
337
+  spi_rx_reg(spi_d); // read any previous data
338
+  spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register
339
+  while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
340
+  while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
341
+  return (uint8)spi_rx_reg(spi_d); // "... and read the last received data."
342
+}
343
+
344
+uint16_t SPIClass::transfer16(uint16_t data) const {
345
+  // Modified by stevestrong: write & read two consecutive bytes in 8 bit mode (DFF=0)
346
+  // This is more effective than two distinct byte transfers
347
+  spi_dev * spi_d = _currentSetting->spi_d;
348
+  spi_rx_reg(spi_d);                   // read any previous data
349
+  spi_tx_reg(spi_d, data>>8);          // write high byte
350
+  while (spi_is_tx_empty(spi_d) == 0); // wait until TXE=1
351
+  while (spi_is_busy(spi_d) != 0);     // wait until BSY=0
352
+  uint16_t ret = spi_rx_reg(spi_d)<<8; // read and shift high byte
353
+  spi_tx_reg(spi_d, data);             // write low byte
354
+  while (spi_is_tx_empty(spi_d) == 0); // wait until TXE=1
355
+  while (spi_is_busy(spi_d) != 0);     // wait until BSY=0
356
+  ret += spi_rx_reg(spi_d);            // read low byte
357
+  return ret;
358
+}
359
+
360
+/*  Roger Clark and Victor Perez, 2015
361
+* Performs a DMA SPI transfer with at least a receive buffer.
362
+* If a TX buffer is not provided, FF is sent over and over for the lenght of the transfer.
363
+* On exit TX buffer is not modified, and RX buffer cotains the received data.
364
+* Still in progress.
365
+*/
366
+void SPIClass::dmaTransferSet(const void *transmitBuf, void *receiveBuf) {
367
+  dma_init(_currentSetting->spiDmaDev);
368
+  //spi_rx_dma_enable(_currentSetting->spi_d);
369
+  //spi_tx_dma_enable(_currentSetting->spi_d);
370
+  dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
371
+  dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR,
372
+      dma_bit_size, receiveBuf, dma_bit_size, (DMA_MINC_MODE | DMA_TRNS_CMPLT ));// receive buffer DMA
373
+  if (!transmitBuf) {
374
+    transmitBuf = &ff;
375
+    dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR,
376
+        dma_bit_size, (volatile void*)transmitBuf, dma_bit_size, (DMA_FROM_MEM));// Transmit FF repeatedly
377
+  }
378
+  else {
379
+    dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR,
380
+        dma_bit_size, (volatile void*)transmitBuf, dma_bit_size, (DMA_MINC_MODE |  DMA_FROM_MEM ));// Transmit buffer DMA
381
+  }
382
+  dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW);
383
+  dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, DMA_PRIORITY_VERY_HIGH);
384
+}
385
+
386
+uint8_t SPIClass::dmaTransferRepeat(uint16_t length) {
387
+  if (length == 0) return 0;
388
+  if (spi_is_rx_nonempty(_currentSetting->spi_d) == 1) spi_rx_reg(_currentSetting->spi_d);
389
+  _currentSetting->state = SPI_STATE_TRANSFER;
390
+  dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length);
391
+  dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
392
+  dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive
393
+  dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
394
+  spi_rx_dma_enable(_currentSetting->spi_d);
395
+  spi_tx_dma_enable(_currentSetting->spi_d);
396
+  if (_currentSetting->receiveCallback)
397
+    return 0;
398
+
399
+  //uint32_t m = millis();
400
+  uint8_t b = 0;
401
+  uint32_t m = millis();
402
+  while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1) == 0) {
403
+    //Avoid interrupts and just loop waiting for the flag to be set.
404
+    if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
405
+  }
406
+
407
+  while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
408
+  while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
409
+  spi_tx_dma_disable(_currentSetting->spi_d);
410
+  spi_rx_dma_disable(_currentSetting->spi_d);
411
+  dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
412
+  dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
413
+  dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
414
+  dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
415
+  _currentSetting->state = SPI_STATE_READY;
416
+  return b;
417
+}
418
+
419
+/* Roger Clark and Victor Perez, 2015
420
+ * Performs a DMA SPI transfer with at least a receive buffer.
421
+ * If a TX buffer is not provided, FF is sent over and over for the length of the transfer.
422
+ * On exit TX buffer is not modified, and RX buffer contains the received data.
423
+ * Still in progress.
424
+ */
425
+uint8_t SPIClass::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) {
426
+  dmaTransferSet(transmitBuf, receiveBuf);
427
+  return dmaTransferRepeat(length);
428
+}
429
+
430
+/* Roger Clark and Victor Perez, 2015
431
+ * Performs a DMA SPI send using a TX buffer.
432
+ * On exit TX buffer is not modified.
433
+ * Still in progress.
434
+ * 2016 - stevstrong - reworked to automatically detect bit size from SPI setting
435
+ */
436
+void SPIClass::dmaSendSet(const void * transmitBuf, bool minc) {
437
+  uint32_t flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
438
+  dma_init(_currentSetting->spiDmaDev);
439
+  dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
440
+  dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
441
+             (volatile void*)transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
442
+  dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW);
443
+}
444
+
445
+uint8_t SPIClass::dmaSendRepeat(uint16_t length) {
446
+  if (length == 0) return 0;
447
+
448
+  dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
449
+  dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
450
+  _currentSetting->state = SPI_STATE_TRANSMIT;
451
+  dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
452
+  spi_tx_dma_enable(_currentSetting->spi_d);
453
+  if (_currentSetting->transmitCallback)
454
+    return 0;
455
+
456
+  uint32_t m = millis();
457
+  uint8_t b = 0;
458
+  while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {
459
+    //Avoid interrupts and just loop waiting for the flag to be set.
460
+    if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
461
+  }
462
+  while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
463
+  while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
464
+  spi_tx_dma_disable(_currentSetting->spi_d);
465
+  dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
466
+  dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
467
+  _currentSetting->state = SPI_STATE_READY;
468
+  return b;
469
+}
470
+
471
+uint8_t SPIClass::dmaSend(const void * transmitBuf, uint16_t length, bool minc) {
472
+  dmaSendSet(transmitBuf, minc);
473
+  return dmaSendRepeat(length);
474
+}
475
+
476
+uint8_t SPIClass::dmaSendAsync(const void * transmitBuf, uint16_t length, bool minc) {
477
+  uint8_t b = 0;
478
+
479
+  if (_currentSetting->state != SPI_STATE_READY) {
480
+    uint32_t m = millis();
481
+    while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {
482
+      //Avoid interrupts and just loop waiting for the flag to be set.
483
+      //delayMicroseconds(10);
484
+      if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
485
+    }
486
+
487
+    while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
488
+    while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
489
+    spi_tx_dma_disable(_currentSetting->spi_d);
490
+    dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
491
+    _currentSetting->state = SPI_STATE_READY;
492
+  }
493
+
494
+  if (length == 0) return 0;
495
+  uint32_t flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
496
+
497
+  dma_init(_currentSetting->spiDmaDev);
498
+  // TX
499
+  dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
500
+  dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR,
501
+      dma_bit_size, (volatile void*)transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
502
+  dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
503
+  dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
504
+  dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
505
+  spi_tx_dma_enable(_currentSetting->spi_d);
506
+
507
+  _currentSetting->state = SPI_STATE_TRANSMIT;
508
+  return b;
509
+}
510
+
511
+
512
+/**
513
+ *  New functions added to manage callbacks.
514
+ *  Victor Perez 2017
515
+ */
516
+void SPIClass::onReceive(void(*callback)(void)) {
517
+  _currentSetting->receiveCallback = callback;
518
+  if (callback) {
519
+    switch (_currentSetting->spi_d->clk_id) {
520
+    #if BOARD_NR_SPI >= 1
521
+    case RCC_SPI1:
522
+      dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback);
523
+      break;
524
+    #endif
525
+    #if BOARD_NR_SPI >= 2
526
+    case RCC_SPI2:
527
+      dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback);
528
+      break;
529
+    #endif
530
+    #if BOARD_NR_SPI >= 3
531
+    case RCC_SPI3:
532
+      dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback);
533
+      break;
534
+    #endif
535
+    default:
536
+      ASSERT(0);
537
+    }
538
+  }
539
+  else {
540
+    dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
541
+  }
542
+}
543
+
544
+void SPIClass::onTransmit(void(*callback)(void)) {
545
+  _currentSetting->transmitCallback = callback;
546
+  if (callback) {
547
+    switch (_currentSetting->spi_d->clk_id) {
548
+    #if BOARD_NR_SPI >= 1
549
+    case RCC_SPI1:
550
+      dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback);
551
+      break;
552
+    #endif
553
+    #if BOARD_NR_SPI >= 2
554
+     case RCC_SPI2:
555
+      dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback);
556
+      break;
557
+    #endif
558
+    #if BOARD_NR_SPI >= 3
559
+    case RCC_SPI3:
560
+      dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback);
561
+      break;
562
+    #endif
563
+    default:
564
+      ASSERT(0);
565
+    }
566
+  }
567
+  else {
568
+    dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
569
+  }
570
+}
571
+
572
+/**
573
+ * TODO: check if better to first call the customer code, next disable the DMA requests.
574
+ * Also see if we need to check whether callbacks are set or not, may be better to be checked
575
+ * during the initial setup and only set the callback to EventCallback if they are set.
576
+ */
577
+void SPIClass::EventCallback() {
578
+  while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
579
+  while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0"
580
+  switch (_currentSetting->state) {
581
+  case SPI_STATE_TRANSFER:
582
+    while (spi_is_rx_nonempty(_currentSetting->spi_d));
583
+    _currentSetting->state = SPI_STATE_READY;
584
+    spi_tx_dma_disable(_currentSetting->spi_d);
585
+    spi_rx_dma_disable(_currentSetting->spi_d);
586
+    //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
587
+    //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
588
+    if (_currentSetting->receiveCallback)
589
+      _currentSetting->receiveCallback();
590
+    break;
591
+  case SPI_STATE_TRANSMIT:
592
+    _currentSetting->state = SPI_STATE_READY;
593
+    spi_tx_dma_disable(_currentSetting->spi_d);
594
+    //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
595
+    if (_currentSetting->transmitCallback)
596
+      _currentSetting->transmitCallback();
597
+    break;
598
+  default:
599
+    break;
600
+  }
601
+}
602
+
603
+void SPIClass::attachInterrupt() {
604
+  // Should be enableInterrupt()
605
+}
606
+
607
+void SPIClass::detachInterrupt() {
608
+  // Should be disableInterrupt()
609
+}
610
+
611
+/*
612
+ * Pin accessors
613
+ */
614
+
615
+uint8_t SPIClass::misoPin() {
616
+  return dev_to_spi_pins(_currentSetting->spi_d)->miso;
617
+}
618
+
619
+uint8_t SPIClass::mosiPin() {
620
+  return dev_to_spi_pins(_currentSetting->spi_d)->mosi;
621
+}
622
+
623
+uint8_t SPIClass::sckPin() {
624
+  return dev_to_spi_pins(_currentSetting->spi_d)->sck;
625
+}
626
+
627
+uint8_t SPIClass::nssPin() {
628
+  return dev_to_spi_pins(_currentSetting->spi_d)->nss;
629
+}
630
+
631
+/*
632
+ * Deprecated functions
633
+ */
634
+
635
+uint8_t SPIClass::send(uint8_t data) {
636
+  this->write(data);
637
+  return 1;
638
+}
639
+
640
+uint8_t SPIClass::send(uint8_t *buf, uint32_t len) {
641
+  this->write(buf, len);
642
+  return len;
643
+}
644
+
645
+uint8_t SPIClass::recv() {
646
+  return this->read();
647
+}
648
+
649
+/*
650
+ * DMA call back functions, one per port.
651
+ */
652
+#if BOARD_NR_SPI >= 1
653
+  void SPIClass::_spi1EventCallback() {
654
+    reinterpret_cast<class SPIClass*>(_spi1_this)->EventCallback();
655
+  }
656
+#endif
657
+#if BOARD_NR_SPI >= 2
658
+  void SPIClass::_spi2EventCallback() {
659
+    reinterpret_cast<class SPIClass*>(_spi2_this)->EventCallback();
660
+  }
661
+#endif
662
+#if BOARD_NR_SPI >= 3
663
+  void SPIClass::_spi3EventCallback() {
664
+    reinterpret_cast<class SPIClass*>(_spi3_this)->EventCallback();
665
+  }
666
+#endif
667
+
668
+/*
669
+ * Auxiliary functions
670
+ */
671
+static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
672
+  switch (dev->clk_id) {
673
+    #if BOARD_NR_SPI >= 1
674
+      case RCC_SPI1: return board_spi_pins;
675
+    #endif
676
+    #if BOARD_NR_SPI >= 2
677
+      case RCC_SPI2: return board_spi_pins + 1;
678
+    #endif
679
+    #if BOARD_NR_SPI >= 3
680
+      case RCC_SPI3: return board_spi_pins + 2;
681
+    #endif
682
+    default: return NULL;
683
+  }
684
+}
685
+
686
+static void disable_pwm(const stm32_pin_info *i) {
687
+  if (i->timer_device)
688
+    timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED);
689
+}
690
+
691
+static void configure_gpios(spi_dev *dev, bool as_master) {
692
+  const spi_pins *pins = dev_to_spi_pins(dev);
693
+  if (!pins) return;
694
+
695
+  const stm32_pin_info *nssi = &PIN_MAP[pins->nss],
696
+                       *scki = &PIN_MAP[pins->sck],
697
+                       *misoi = &PIN_MAP[pins->miso],
698
+                       *mosii = &PIN_MAP[pins->mosi];
699
+
700
+  disable_pwm(nssi);
701
+  disable_pwm(scki);
702
+  disable_pwm(misoi);
703
+  disable_pwm(mosii);
704
+
705
+  spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit,
706
+  scki->gpio_device, scki->gpio_bit, misoi->gpio_bit,
707
+  mosii->gpio_bit);
708
+}
709
+
710
+static const spi_baud_rate baud_rates[8] __FLASH__ = {
711
+  SPI_BAUD_PCLK_DIV_2,
712
+  SPI_BAUD_PCLK_DIV_4,
713
+  SPI_BAUD_PCLK_DIV_8,
714
+  SPI_BAUD_PCLK_DIV_16,
715
+  SPI_BAUD_PCLK_DIV_32,
716
+  SPI_BAUD_PCLK_DIV_64,
717
+  SPI_BAUD_PCLK_DIV_128,
718
+  SPI_BAUD_PCLK_DIV_256,
719
+};
720
+
721
+/*
722
+* Note: This assumes you're on a LeafLabs-style board
723
+* (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
724
+*/
725
+static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) {
726
+  uint32_t clock = 0;
727
+  switch (rcc_dev_clk(dev->clk_id)) {
728
+    case RCC_AHB:
729
+    case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz
730
+    case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz
731
+  }
732
+  clock >>= 1;
733
+
734
+  uint8_t i = 0;
735
+  while (i < 7 && freq < clock) { clock >>= 1; i++; }
736
+  return baud_rates[i];
737
+}
738
+
739
+SPIClass SPI(1);
740
+
741
+#endif // __STM32F1__

+ 409
- 0
Marlin/src/HAL/HAL_STM32F1/SPI.h View File

@@ -0,0 +1,409 @@
1
+/******************************************************************************
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2010 Perry Hung.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *****************************************************************************/
26
+#pragma once
27
+
28
+#include <libmaple/libmaple_types.h>
29
+#include <libmaple/spi.h>
30
+#include <libmaple/dma.h>
31
+
32
+#include <boards.h>
33
+#include <stdint.h>
34
+#include <wirish.h>
35
+
36
+// SPI_HAS_TRANSACTION means SPI has
37
+//   - beginTransaction()
38
+//   - endTransaction()
39
+//   - usingInterrupt()
40
+//   - SPISetting(clock, bitOrder, dataMode)
41
+//#define SPI_HAS_TRANSACTION
42
+
43
+#define SPI_CLOCK_DIV2   SPI_BAUD_PCLK_DIV_2
44
+#define SPI_CLOCK_DIV4   SPI_BAUD_PCLK_DIV_4
45
+#define SPI_CLOCK_DIV8   SPI_BAUD_PCLK_DIV_8
46
+#define SPI_CLOCK_DIV16  SPI_BAUD_PCLK_DIV_16
47
+#define SPI_CLOCK_DIV32  SPI_BAUD_PCLK_DIV_32
48
+#define SPI_CLOCK_DIV64  SPI_BAUD_PCLK_DIV_64
49
+#define SPI_CLOCK_DIV128 SPI_BAUD_PCLK_DIV_128
50
+#define SPI_CLOCK_DIV256 SPI_BAUD_PCLK_DIV_256
51
+
52
+/*
53
+ * Roger Clark. 20150106
54
+ * Commented out redundant AVR defined
55
+ *
56
+#define SPI_MODE_MASK 0x0C     // CPOL = bit 3, CPHA = bit 2 on SPCR
57
+#define SPI_CLOCK_MASK 0x03    // SPR1 = bit 1, SPR0 = bit 0 on SPCR
58
+#define SPI_2XCLOCK_MASK 0x01  // SPI2X = bit 0 on SPSR
59
+
60
+// define SPI_AVR_EIMSK for AVR boards with external interrupt pins
61
+#if defined(EIMSK)
62
+  #define SPI_AVR_EIMSK EIMSK
63
+#elif defined(GICR)
64
+  #define SPI_AVR_EIMSK GICR
65
+#elif defined(GIMSK)
66
+  #define SPI_AVR_EIMSK GIMSK
67
+#endif
68
+*/
69
+
70
+#ifndef STM32_LSBFIRST
71
+  #define STM32_LSBFIRST 0
72
+#endif
73
+#ifndef STM32_MSBFIRST
74
+  #define STM32_MSBFIRST 1
75
+#endif
76
+
77
+// PC13 or PA4
78
+#define BOARD_SPI_DEFAULT_SS PA4
79
+//#define BOARD_SPI_DEFAULT_SS PC13
80
+
81
+#define SPI_MODE0 SPI_MODE_0
82
+#define SPI_MODE1 SPI_MODE_1
83
+#define SPI_MODE2 SPI_MODE_2
84
+#define SPI_MODE3 SPI_MODE_3
85
+
86
+#define DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT
87
+#define DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT
88
+
89
+typedef enum {
90
+  SPI_STATE_IDLE,
91
+  SPI_STATE_READY,
92
+  SPI_STATE_RECEIVE,
93
+  SPI_STATE_TRANSMIT,
94
+  SPI_STATE_TRANSFER
95
+} spi_mode_t;
96
+
97
+class SPISettings {
98
+public:
99
+  SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
100
+    if (__builtin_constant_p(clock))
101
+      init_AlwaysInline(clock, bitOrder, dataMode, DATA_SIZE_8BIT);
102
+    else
103
+      init_MightInline(clock, bitOrder, dataMode, DATA_SIZE_8BIT);
104
+  }
105
+  SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) {
106
+    if (__builtin_constant_p(clock))
107
+      init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
108
+    else
109
+      init_MightInline(clock, bitOrder, dataMode, dataSize);
110
+  }
111
+  SPISettings(uint32_t clock) {
112
+    if (__builtin_constant_p(clock))
113
+      init_AlwaysInline(clock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
114
+    else
115
+      init_MightInline(clock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
116
+  }
117
+  SPISettings() {
118
+    init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
119
+  }
120
+private:
121
+  void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) {
122
+    init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
123
+  }
124
+  void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) __attribute__((__always_inline__)) {
125
+    this->clock = clock;
126
+    this->bitOrder = bitOrder;
127
+    this->dataMode = dataMode;
128
+    this->dataSize = dataSize;
129
+  }
130
+  uint32_t clock;
131
+  uint32_t dataSize;
132
+  uint32_t clockDivider;
133
+  BitOrder bitOrder;
134
+  uint8_t dataMode;
135
+  uint8_t _SSPin;
136
+  volatile spi_mode_t state;
137
+  spi_dev *spi_d;
138
+  dma_channel spiRxDmaChannel, spiTxDmaChannel;
139
+  dma_dev* spiDmaDev;
140
+  void (*receiveCallback)(void) = NULL;
141
+  void (*transmitCallback)(void) = NULL;
142
+
143
+  friend class SPIClass;
144
+};
145
+
146
+/*
147
+ * Kept for compat.
148
+ */
149
+static const uint8_t ff = 0xFF;
150
+
151
+/**
152
+ * @brief Wirish SPI interface.
153
+ *
154
+ * This implementation uses software slave management, so the caller
155
+ * is responsible for controlling the slave select line.
156
+ */
157
+class SPIClass {
158
+
159
+public:
160
+  /**
161
+   * @param spiPortNumber Number of the SPI port to manage.
162
+   */
163
+  SPIClass(uint32_t spiPortNumber);
164
+
165
+  /**
166
+   * @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
167
+   */
168
+  void begin();
169
+
170
+  /**
171
+   * @brief Turn on a SPI port and set its GPIO pin modes for use as a slave.
172
+   *
173
+   * SPI port is enabled in full duplex mode, with software slave management.
174
+   *
175
+   * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian)
176
+   * @param mode SPI mode to use
177
+   */
178
+  void beginSlave(uint32_t bitOrder, uint32_t mode);
179
+
180
+  /**
181
+   * @brief Equivalent to beginSlave(MSBFIRST, 0).
182
+   */
183
+  void beginSlave();
184
+
185
+  /**
186
+   * @brief Disables the SPI port, but leaves its GPIO pin modes unchanged.
187
+   */
188
+  void end();
189
+
190
+  void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); }
191
+  void beginTransaction(uint8_t pin, SPISettings settings);
192
+  void endTransaction();
193
+
194
+  void beginTransactionSlave(SPISettings settings);
195
+
196
+  void setClockDivider(uint32_t clockDivider);
197
+  void setBitOrder(BitOrder bitOrder);
198
+  void setDataMode(uint8_t dataMode);
199
+
200
+  // SPI Configuration methods
201
+  void attachInterrupt();
202
+  void detachInterrupt();
203
+
204
+  /* Victor Perez. Added to change datasize from 8 to 16 bit modes on the fly.
205
+   * Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word.
206
+   * Requires an added function spi_data_size on STM32F1 / cores / maple / libmaple / spi.c
207
+   */
208
+  void setDataSize(uint32_t ds);
209
+
210
+  /* Victor Perez 2017. Added to set and clear callback functions for callback
211
+   * on DMA transfer completion.
212
+   * onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed
213
+   * onTransmit used to set the callback in case of dmaSend (tx only). That function
214
+   * will NOT be called in case of TX/RX
215
+   */
216
+  void onReceive(void(*)(void));
217
+  void onTransmit(void(*)(void));
218
+
219
+  /*
220
+   * I/O
221
+   */
222
+
223
+  /**
224
+   * @brief Return the next unread byte/word.
225
+   *
226
+   * If there is no unread byte/word waiting, this function will block
227
+   * until one is received.
228
+   */
229
+  uint16_t read();
230
+
231
+  /**
232
+   * @brief Read length bytes, storing them into buffer.
233
+   * @param buffer Buffer to store received bytes into.
234
+   * @param length Number of bytes to store in buffer. This
235
+   *               function will block until the desired number of
236
+   *               bytes have been read.
237
+   */
238
+  void read(uint8_t *buffer, uint32_t length);
239
+
240
+  /**
241
+   * @brief Transmit one byte/word.
242
+   * @param data to transmit.
243
+   */
244
+  void write(uint16_t data);
245
+  void write16(uint16_t data); // write 2 bytes in 8 bit mode (DFF=0)
246
+
247
+  /**
248
+   * @brief Transmit one byte/word a specified number of times.
249
+   * @param data to transmit.
250
+   */
251
+  void write(uint16_t data, uint32_t n);
252
+
253
+  /**
254
+   * @brief Transmit multiple bytes/words.
255
+   * @param buffer Bytes/words to transmit.
256
+   * @param length Number of bytes/words in buffer to transmit.
257
+   */
258
+  void write(const void * buffer, uint32_t length);
259
+
260
+  /**
261
+   * @brief Transmit a byte, then return the next unread byte.
262
+   *
263
+   * This function transmits before receiving.
264
+   *
265
+   * @param data Byte to transmit.
266
+   * @return Next unread byte.
267
+   */
268
+  uint8_t transfer(uint8_t data) const;
269
+  uint16_t transfer16(uint16_t data) const;
270
+
271
+  /**
272
+   * @brief Sets up a DMA Transfer for "length" bytes.
273
+   * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting.
274
+   *
275
+   * This function transmits and receives to buffers.
276
+   *
277
+   * @param transmitBuf buffer Bytes to transmit. If passed as 0, it sends FF repeatedly for "length" bytes
278
+   * @param receiveBuf buffer Bytes to save received data.
279
+   * @param length Number of bytes in buffer to transmit.
280
+   */
281
+  uint8_t dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16_t length);
282
+  void dmaTransferSet(const void *transmitBuf, void *receiveBuf);
283
+  uint8_t dmaTransferRepeat(uint16_t length);
284
+
285
+  /**
286
+   * @brief Sets up a DMA Transmit for SPI 8 or 16 bit transfer mode.
287
+   * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting.
288
+   *
289
+   * This function only transmits and does not care about the RX fifo.
290
+   *
291
+   * @param data buffer half words to transmit,
292
+   * @param length Number of bytes in buffer to transmit.
293
+   * @param minc Set to use Memory Increment mode, clear to use Circular mode.
294
+   */
295
+  uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = 1);
296
+  void dmaSendSet(const void * transmitBuf, bool minc);
297
+  uint8_t dmaSendRepeat(uint16_t length);
298
+
299
+  uint8_t dmaSendAsync(const void * transmitBuf, uint16_t length, bool minc = 1);
300
+  /*
301
+   * Pin accessors
302
+   */
303
+
304
+  /**
305
+   * @brief Return the number of the MISO (master in, slave out) pin
306
+   */
307
+  uint8_t misoPin();
308
+
309
+  /**
310
+   * @brief Return the number of the MOSI (master out, slave in) pin
311
+   */
312
+  uint8_t mosiPin();
313
+
314
+  /**
315
+   * @brief Return the number of the SCK (serial clock) pin
316
+   */
317
+  uint8_t sckPin();
318
+
319
+  /**
320
+   * @brief Return the number of the NSS (slave select) pin
321
+   */
322
+  uint8_t nssPin();
323
+
324
+  /* Escape hatch */
325
+
326
+  /**
327
+   * @brief Get a pointer to the underlying libmaple spi_dev for
328
+   *        this HardwareSPI instance.
329
+   */
330
+  spi_dev* c_dev(void) { return _currentSetting->spi_d; }
331
+
332
+  spi_dev* dev() { return _currentSetting->spi_d; }
333
+
334
+  /**
335
+   * @brief Sets the number of the SPI peripheral to be used by
336
+   *        this HardwareSPI instance.
337
+   *
338
+   * @param spi_num Number of the SPI port. 1-2 in low density devices
339
+   *     or 1-3 in high density devices.
340
+   */
341
+  void setModule(int spi_num) {
342
+    _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
343
+  }
344
+
345
+  /* -- The following methods are deprecated --------------------------- */
346
+
347
+  /**
348
+   * @brief Deprecated.
349
+   *
350
+   * Use HardwareSPI::transfer() instead.
351
+   *
352
+   * @see HardwareSPI::transfer()
353
+   */
354
+  uint8_t send(uint8_t data);
355
+
356
+  /**
357
+   * @brief Deprecated.
358
+   *
359
+   * Use HardwareSPI::write() in combination with
360
+   * HardwareSPI::read() (or HardwareSPI::transfer()) instead.
361
+   *
362
+   * @see HardwareSPI::write()
363
+   * @see HardwareSPI::read()
364
+   * @see HardwareSPI::transfer()
365
+   */
366
+  uint8_t send(uint8_t *data, uint32_t length);
367
+
368
+  /**
369
+   * @brief Deprecated.
370
+   *
371
+   * Use HardwareSPI::read() instead.
372
+   *
373
+   * @see HardwareSPI::read()
374
+   */
375
+  uint8_t recv();
376
+
377
+private:
378
+
379
+  SPISettings _settings[BOARD_NR_SPI];
380
+  SPISettings *_currentSetting;
381
+
382
+  void updateSettings();
383
+
384
+  /*
385
+   * Functions added for DMA transfers with Callback.
386
+   * Experimental.
387
+   */
388
+
389
+  void EventCallback();
390
+
391
+  #if BOARD_NR_SPI >= 1
392
+    static void _spi1EventCallback();
393
+  #endif
394
+  #if BOARD_NR_SPI >= 2
395
+    static void _spi2EventCallback();
396
+  #endif
397
+  #if BOARD_NR_SPI >= 3
398
+    static void _spi3EventCallback();
399
+  #endif
400
+  /*
401
+  spi_dev *spi_d;
402
+  uint8_t _SSPin;
403
+  uint32_t clockDivider;
404
+  uint8_t dataMode;
405
+  BitOrder bitOrder;
406
+  */
407
+};
408
+
409
+extern SPIClass SPI;

+ 2
- 2
Marlin/src/HAL/HAL_STM32F1/fastio_STM32F1.h View File

@@ -38,8 +38,8 @@
38 38
 #define _SET_OUTPUT(IO)       _SET_MODE(IO, GPIO_OUTPUT_PP)
39 39
 #define _SET_OUTPUT_OD(IO)    _SET_MODE(IO, GPIO_OUTPUT_OD)
40 40
 
41
-#define OUT_WRITE(IO,V)       do{ _SET_OUTPUT(IO); WRITE(IO,V); } while(0)
42
-#define OUT_WRITE_OD(IO,V)    do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); } while(0)
41
+#define OUT_WRITE(IO,V)       do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
42
+#define OUT_WRITE_OD(IO,V)    do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0)
43 43
 
44 44
 #define SET_INPUT(IO)         _SET_MODE(IO, GPIO_INPUT_FLOATING)
45 45
 #define SET_INPUT_PULLUP(IO)  _SET_MODE(IO, GPIO_INPUT_PU)

+ 10
- 26
Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp View File

@@ -42,7 +42,6 @@
42 42
 // Store settings in the last two pages
43 43
 // Flash pages must be erased before writing, so keep track.
44 44
 bool firstWrite = false;
45
-uint32_t pageBase = EEPROM_START_ADDRESS;
46 45
 
47 46
 bool PersistentStore::access_start() {
48 47
   firstWrite = true;
@@ -67,42 +66,27 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
67 66
     firstWrite = false;
68 67
   }
69 68
 
70
-  // First write full words
71
-  int i = 0;
72
-  int wordsToWrite = size / sizeof(uint16_t);
73
-  uint16_t* wordBuffer = (uint16_t *)value;
74
-  while (wordsToWrite) {
75
-    status = FLASH_ProgramHalfWord(pageBase + pos + (i * 2), wordBuffer[i]);
76
-    if (status != FLASH_COMPLETE) return true;
77
-    wordsToWrite--;
78
-    i++;
79
-  }
80
-
81
-  // Now, write any remaining single byte
82
-  const uint16_t odd = size & 1;
83
-  if (odd) {
84
-    uint16_t temp = value[size - 1];
85
-    status = FLASH_ProgramHalfWord(pageBase + pos + i, temp);
86
-    if (status != FLASH_COMPLETE) return true;
69
+  for (size_t i = 0; i < size; i++) {
70
+    if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + (pos + i) * 2, value[i]) != FLASH_COMPLETE)
71
+      return true;
87 72
   }
88 73
 
89 74
   crc16(crc, value, size);
90
-  pos += size + odd;
75
+  pos += size;
91 76
   return false;
92 77
 }
93 78
 
94 79
 bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
95
-  for (uint16_t i = 0; i < size; i++) {
96
-    byte* accessPoint = (byte*)(pageBase + pos + i);
97
-    uint8_t c = *accessPoint;
98
-    if (writing) value[i] = c;
99
-    crc16(crc, &c, 1);
80
+  for (size_t i = 0; i < size; i++) {
81
+    uint8_t v = *(uint16_t *)(EEPROM_PAGE0_BASE + (pos + i) * 2);
82
+    if (writing) value[i] = v;
83
+    crc16(crc, &v, 1);
100 84
   }
101
-  pos += ((size + 1) & ~1); // i.e., size+(size&1), round up odd values
85
+  pos += size;
102 86
   return false;
103 87
 }
104 88
 
105
-size_t PersistentStore::capacity() { return E2END + 1; }
89
+size_t PersistentStore::capacity() { return size_t(E2END + 1); }
106 90
 
107 91
 #endif // EEPROM_SETTINGS && EEPROM FLASH
108 92
 #endif // __STM32F1__

+ 21
- 37
Marlin/src/HAL/HAL_STM32_F4_F7/STM32F4/HAL_timers_STM32F4.cpp View File

@@ -53,56 +53,40 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
53 53
     switch (timer_num) {
54 54
       case STEP_TIMER_NUM:
55 55
         // STEPPER TIMER TIM5 - use a 32bit timer
56
-        #ifdef STM32GENERIC
57
-          __HAL_RCC_TIM5_CLK_ENABLE();
58
-          TimerHandle[timer_num].handle.Instance            = TIM5;
59
-          TimerHandle[timer_num].handle.Init.Prescaler      = step_prescaler;
60
-          TimerHandle[timer_num].handle.Init.CounterMode    = TIM_COUNTERMODE_UP;
61
-          TimerHandle[timer_num].handle.Init.ClockDivision  = TIM_CLOCKDIVISION_DIV1;
62
-          TimerHandle[timer_num].callback = (uint32_t)TC5_Handler;
63
-        #else
64
-          TimerHandle[timer_num].timer = TIM5;
65
-          TimerHandle[timer_num].irqHandle = TC5_Handler;
66
-          TimerHandleInit(&TimerHandle[timer_num], (((HAL_TIMER_RATE) / step_prescaler) / frequency) - 1, step_prescaler);
67
-        #endif
56
+        __HAL_RCC_TIM5_CLK_ENABLE();
57
+        TimerHandle[timer_num].handle.Instance            = TIM5;
58
+        TimerHandle[timer_num].handle.Init.Prescaler      = step_prescaler;
59
+        TimerHandle[timer_num].handle.Init.CounterMode    = TIM_COUNTERMODE_UP;
60
+        TimerHandle[timer_num].handle.Init.ClockDivision  = TIM_CLOCKDIVISION_DIV1;
61
+        TimerHandle[timer_num].callback = (uint32_t)TC5_Handler;
68 62
         HAL_NVIC_SetPriority(STEP_TIMER_IRQ_ID, 1, 0);
69 63
         break;
70 64
 
71 65
       case TEMP_TIMER_NUM:
72 66
         // TEMP TIMER TIM7 - any available 16bit Timer (1 already used for PWM)
73
-        #ifdef STM32GENERIC
74
-          __HAL_RCC_TIM7_CLK_ENABLE();
75
-          TimerHandle[timer_num].handle.Instance            = TIM7;
76
-          TimerHandle[timer_num].handle.Init.Prescaler      = temp_prescaler;
77
-          TimerHandle[timer_num].handle.Init.CounterMode    = TIM_COUNTERMODE_UP;
78
-          TimerHandle[timer_num].handle.Init.ClockDivision  = TIM_CLOCKDIVISION_DIV1;
79
-          TimerHandle[timer_num].callback = (uint32_t)TC7_Handler;
80
-        #else
81
-          TimerHandle[timer_num].timer = TIM7;
82
-          TimerHandle[timer_num].irqHandle = TC7_Handler;
83
-          TimerHandleInit(&TimerHandle[timer_num], (((HAL_TIMER_RATE) / temp_prescaler) / frequency) - 1, temp_prescaler);
84
-        #endif
67
+        __HAL_RCC_TIM7_CLK_ENABLE();
68
+        TimerHandle[timer_num].handle.Instance            = TIM7;
69
+        TimerHandle[timer_num].handle.Init.Prescaler      = temp_prescaler;
70
+        TimerHandle[timer_num].handle.Init.CounterMode    = TIM_COUNTERMODE_UP;
71
+        TimerHandle[timer_num].handle.Init.ClockDivision  = TIM_CLOCKDIVISION_DIV1;
72
+        TimerHandle[timer_num].callback = (uint32_t)TC7_Handler;
85 73
         HAL_NVIC_SetPriority(TEMP_TIMER_IRQ_ID, 2, 0);
86 74
         break;
87 75
     }
88 76
     timers_initialized[timer_num] = true;
89 77
   }
90 78
 
91
-  #ifdef STM32GENERIC
92
-    TimerHandle[timer_num].handle.Init.Period = (((HAL_TIMER_RATE) / TimerHandle[timer_num].handle.Init.Prescaler) / frequency) - 1;
93
-    if (HAL_TIM_Base_Init(&TimerHandle[timer_num].handle) == HAL_OK)
94
-      HAL_TIM_Base_Start_IT(&TimerHandle[timer_num].handle);
95
-  #endif
79
+  TimerHandle[timer_num].handle.Init.Period = (((HAL_TIMER_RATE) / TimerHandle[timer_num].handle.Init.Prescaler) / frequency) - 1;
80
+  if (HAL_TIM_Base_Init(&TimerHandle[timer_num].handle) == HAL_OK)
81
+    HAL_TIM_Base_Start_IT(&TimerHandle[timer_num].handle);
96 82
 }
97 83
 
98
-#ifdef STM32GENERIC
99
-  extern "C" void TIM5_IRQHandler() {
100
-    ((void(*)(void))TimerHandle[0].callback)();
101
-  }
102
-  extern "C" void TIM7_IRQHandler() {
103
-    ((void(*)(void))TimerHandle[1].callback)();
104
-  }
105
-#endif
84
+extern "C" void TIM5_IRQHandler() {
85
+  ((void(*)(void))TimerHandle[0].callback)();
86
+}
87
+extern "C" void TIM7_IRQHandler() {
88
+  ((void(*)(void))TimerHandle[1].callback)();
89
+}
106 90
 
107 91
 void HAL_timer_enable_interrupt(const uint8_t timer_num) {
108 92
   switch (timer_num) {

+ 3
- 2
Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/HAL_timers_STM32F7.cpp View File

@@ -59,8 +59,9 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
59 59
       timerConfig[0].IRQ_Id = TIM5_IRQn;
60 60
       timerConfig[0].callback = (uint32_t)TC5_Handler;
61 61
       HAL_NVIC_SetPriority(timerConfig[0].IRQ_Id, 1, 0);
62
-      SET_OUTPUT(STEPPER_ENABLE_PIN);
63
-      WRITE(STEPPER_ENABLE_PIN);
62
+      #if PIN_EXISTS(STEPPER_ENABLE)
63
+        OUT_WRITE(STEPPER_ENABLE_PIN, HIGH);
64
+      #endif
64 65
       break;
65 66
     case TEMP_TIMER_NUM:
66 67
       //TEMP TIMER TIM7 // any available 16bit Timer (1 already used for PWM)

+ 0
- 1
Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp View File

@@ -189,7 +189,6 @@ void TMC26XStepper::start() {
189 189
   pinMode(step_pin, OUTPUT);
190 190
   pinMode(dir_pin, OUTPUT);
191 191
   pinMode(cs_pin, OUTPUT);
192
-  //SET_OUTPUT(STEPPER_ENABLE_PIN);
193 192
   extDigitalWrite(step_pin, LOW);
194 193
   extDigitalWrite(dir_pin, LOW);
195 194
   extDigitalWrite(cs_pin, HIGH);

+ 3
- 1
Marlin/src/HAL/HAL_STM32_F4_F7/eeprom_emul.cpp View File

@@ -86,6 +86,8 @@ uint16_t EE_Initialize(void) {
86 86
   pEraseInit.NbSectors = 1;
87 87
   pEraseInit.VoltageRange = VOLTAGE_RANGE;
88 88
 
89
+  HAL_StatusTypeDef FlashStatus; // = HAL_OK
90
+
89 91
   /* Check for invalid header states and repair if necessary */
90 92
   uint32_t SectorError;
91 93
   switch (PageStatus0) {
@@ -135,7 +137,7 @@ uint16_t EE_Initialize(void) {
135 137
           }
136 138
         }
137 139
         /* Mark Page0 as valid */
138
-        HAL_StatusTypeDef FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
140
+        FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
139 141
         /* If program operation was failed, a Flash error code is returned */
140 142
         if (FlashStatus != HAL_OK) return FlashStatus;
141 143
         pEraseInit.Sector = PAGE1_ID;

+ 28
- 11
Marlin/src/Marlin.cpp View File

@@ -65,7 +65,7 @@
65 65
   #include "feature/host_actions.h"
66 66
 #endif
67 67
 
68
-#if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER)
68
+#if USE_BEEPER
69 69
   #include "libs/buzzer.h"
70 70
 #endif
71 71
 
@@ -290,6 +290,15 @@ void enable_all_steppers() {
290 290
   enable_E5();
291 291
 }
292 292
 
293
+void enable_e_steppers() {
294
+  enable_E0();
295
+  enable_E1();
296
+  enable_E2();
297
+  enable_E3();
298
+  enable_E4();
299
+  enable_E5();
300
+}
301
+
293 302
 void disable_e_steppers() {
294 303
   disable_E0();
295 304
   disable_E1();
@@ -539,28 +548,28 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
539 548
       #if ENABLED(SWITCHING_EXTRUDER)
540 549
         bool oldstatus;
541 550
         switch (active_extruder) {
542
-          default: oldstatus = E0_ENABLE_READ; enable_E0(); break;
551
+          default: oldstatus = E0_ENABLE_READ(); enable_E0(); break;
543 552
           #if E_STEPPERS > 1
544
-            case 2: case 3: oldstatus = E1_ENABLE_READ; enable_E1(); break;
553
+            case 2: case 3: oldstatus = E1_ENABLE_READ(); enable_E1(); break;
545 554
             #if E_STEPPERS > 2
546
-              case 4: case 5: oldstatus = E2_ENABLE_READ; enable_E2(); break;
555
+              case 4: case 5: oldstatus = E2_ENABLE_READ(); enable_E2(); break;
547 556
             #endif // E_STEPPERS > 2
548 557
           #endif // E_STEPPERS > 1
549 558
         }
550 559
       #else // !SWITCHING_EXTRUDER
551 560
         bool oldstatus;
552 561
         switch (active_extruder) {
553
-          default: oldstatus = E0_ENABLE_READ; enable_E0(); break;
562
+          default: oldstatus = E0_ENABLE_READ(); enable_E0(); break;
554 563
           #if E_STEPPERS > 1
555
-            case 1: oldstatus = E1_ENABLE_READ; enable_E1(); break;
564
+            case 1: oldstatus = E1_ENABLE_READ(); enable_E1(); break;
556 565
             #if E_STEPPERS > 2
557
-              case 2: oldstatus = E2_ENABLE_READ; enable_E2(); break;
566
+              case 2: oldstatus = E2_ENABLE_READ(); enable_E2(); break;
558 567
               #if E_STEPPERS > 3
559
-                case 3: oldstatus = E3_ENABLE_READ; enable_E3(); break;
568
+                case 3: oldstatus = E3_ENABLE_READ(); enable_E3(); break;
560 569
                 #if E_STEPPERS > 4
561
-                  case 4: oldstatus = E4_ENABLE_READ; enable_E4(); break;
570
+                  case 4: oldstatus = E4_ENABLE_READ(); enable_E4(); break;
562 571
                   #if E_STEPPERS > 5
563
-                    case 5: oldstatus = E5_ENABLE_READ; enable_E5(); break;
572
+                    case 5: oldstatus = E5_ENABLE_READ(); enable_E5(); break;
564 573
                   #endif // E_STEPPERS > 5
565 574
                 #endif // E_STEPPERS > 4
566 575
               #endif // E_STEPPERS > 3
@@ -693,7 +702,7 @@ void idle(
693 702
     print_job_timer.tick();
694 703
   #endif
695 704
 
696
-  #if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER) && DISABLED(PCA9632_BUZZER)
705
+  #if USE_BEEPER
697 706
     buzzer.tick();
698 707
   #endif
699 708
 
@@ -877,6 +886,10 @@ void setup() {
877 886
     runout.setup();
878 887
   #endif
879 888
 
889
+  #if ENABLED(POWER_LOSS_RECOVERY)
890
+    recovery.setup();
891
+  #endif
892
+
880 893
   setup_killpin();
881 894
 
882 895
   #if HAS_TMC220x
@@ -1117,6 +1130,10 @@ void setup() {
1117 1130
     init_closedloop();
1118 1131
   #endif
1119 1132
 
1133
+  #ifdef STARTUP_COMMANDS
1134
+    queue.inject_P(PSTR(STARTUP_COMMANDS));
1135
+  #endif
1136
+
1120 1137
   #if ENABLED(INIT_SDCARD_ON_BOOT) && !HAS_SPI_LCD
1121 1138
     card.beginautostart();
1122 1139
   #endif

+ 1
- 0
Marlin/src/Marlin.h View File

@@ -316,6 +316,7 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
316 316
 /**
317 317
  * The axis order in all axis related arrays is X, Y, Z, E
318 318
  */
319
+void enable_e_steppers();
319 320
 void enable_all_steppers();
320 321
 void disable_e_stepper(const uint8_t e);
321 322
 void disable_e_steppers();

+ 21
- 19
Marlin/src/core/boards.h View File

@@ -95,7 +95,7 @@
95 95
 #define BOARD_Z_BOLT_X_SERIES         1141  // Z-Bolt X Series
96 96
 #define BOARD_TT_OSCAR                1142  // TT OSCAR
97 97
 #define BOARD_OVERLORD                1143  // Overlord/Overlord Pro
98
-#define BOARD_ULTIMAKER               1144  // ADIMLab Granty v1
98
+#define BOARD_HJC2560C_REV1           1144  // ADIMLab Granty v1
99 99
 #define BOARD_HJC2560C_REV2           1145  // ADIMLab Granty v2
100 100
 
101 101
 //
@@ -115,24 +115,25 @@
115 115
 
116 116
 #define BOARD_CNCONTROLS_11           1300  // Cartesio CN Controls V11
117 117
 #define BOARD_CNCONTROLS_12           1301  // Cartesio CN Controls V12
118
-#define BOARD_CHEAPTRONIC             1302  // Cheaptronic v1.0
119
-#define BOARD_CHEAPTRONIC_V2          1303  // Cheaptronic v2.0
120
-#define BOARD_MIGHTYBOARD_REVE        1304  // Makerbot Mightyboard Revision E
121
-#define BOARD_MEGATRONICS             1305  // Megatronics
122
-#define BOARD_MEGATRONICS_2           1306  // Megatronics v2.0
123
-#define BOARD_MEGATRONICS_3           1307  // Megatronics v3.0
124
-#define BOARD_MEGATRONICS_31          1308  // Megatronics v3.1
125
-#define BOARD_MEGATRONICS_32          1309  // Megatronics v3.2
126
-#define BOARD_ELEFU_3                 1310  // Elefu Ra Board (v3)
127
-#define BOARD_LEAPFROG                1311  // Leapfrog
128
-#define BOARD_MEGACONTROLLER          1312  // Mega controller
129
-#define BOARD_GT2560_REV_A            1313  // Geeetech GT2560 Rev. A
130
-#define BOARD_GT2560_REV_A_PLUS       1314  // Geeetech GT2560 Rev. A+ (with auto level probe)
131
-#define BOARD_GT2560_V3               1315  // Geeetech GT2560 Rev B for A10(M/D)
132
-#define BOARD_GT2560_V3_MC2           1316  // Geeetech GT2560 Rev B for Mecreator2
133
-#define BOARD_GT2560_V3_A20           1317  // Geeetech GT2560 Rev B for A20(M/D)
134
-#define BOARD_EINSTART_S              1318  // Einstart retrofit
135
-#define BOARD_WANHAO_ONEPLUS          1319  // Wanhao 0ne+ i3 Mini
118
+#define BOARD_CNCONTROLS_15           1302  // Cartesio CN Controls V15
119
+#define BOARD_CHEAPTRONIC             1303  // Cheaptronic v1.0
120
+#define BOARD_CHEAPTRONIC_V2          1304  // Cheaptronic v2.0
121
+#define BOARD_MIGHTYBOARD_REVE        1305  // Makerbot Mightyboard Revision E
122
+#define BOARD_MEGATRONICS             1306  // Megatronics
123
+#define BOARD_MEGATRONICS_2           1307  // Megatronics v2.0
124
+#define BOARD_MEGATRONICS_3           1308  // Megatronics v3.0
125
+#define BOARD_MEGATRONICS_31          1309  // Megatronics v3.1
126
+#define BOARD_MEGATRONICS_32          1310  // Megatronics v3.2
127
+#define BOARD_ELEFU_3                 1311  // Elefu Ra Board (v3)
128
+#define BOARD_LEAPFROG                1312  // Leapfrog
129
+#define BOARD_MEGACONTROLLER          1313  // Mega controller
130
+#define BOARD_GT2560_REV_A            1314  // Geeetech GT2560 Rev. A
131
+#define BOARD_GT2560_REV_A_PLUS       1315  // Geeetech GT2560 Rev. A+ (with auto level probe)
132
+#define BOARD_GT2560_V3               1316  // Geeetech GT2560 Rev B for A10(M/D)
133
+#define BOARD_GT2560_V3_MC2           1317  // Geeetech GT2560 Rev B for Mecreator2
134
+#define BOARD_GT2560_V3_A20           1318  // Geeetech GT2560 Rev B for A20(M/D)
135
+#define BOARD_EINSTART_S              1319  // Einstart retrofit
136
+#define BOARD_WANHAO_ONEPLUS          1320  // Wanhao 0ne+ i3 Mini
136 137
 
137 138
 //
138 139
 // ATmega1281, ATmega2561
@@ -292,6 +293,7 @@
292 293
 #define BOARD_BLACK_STM32F407ZE       4205  // BLACK_STM32F407ZE
293 294
 #define BOARD_STEVAL                  4206  // STEVAL-3DP001V1 3D PRINTER BOARD
294 295
 #define BOARD_BIGTREE_SKR_PRO_V1_1    4207  // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
296
+#define BOARD_BIGTREE_BTT002_V1_0     4208  // BigTreeTech BTT002 v1.0 (STM32F407VE)
295 297
 
296 298
 //
297 299
 // ARM Cortex M7

+ 5
- 3
Marlin/src/core/drivers.h View File

@@ -67,12 +67,14 @@
67 67
 
68 68
 #define AXIS_DRIVER_TYPE(A,T) AXIS_DRIVER_TYPE_##A(T)
69 69
 
70
+#define HAS_E_DRIVER(T) (  AXIS_DRIVER_TYPE_E0(T) || AXIS_DRIVER_TYPE_E1(T) \
71
+                        || AXIS_DRIVER_TYPE_E2(T) || AXIS_DRIVER_TYPE_E3(T) \
72
+                        || AXIS_DRIVER_TYPE_E4(T) || AXIS_DRIVER_TYPE_E5(T) )
73
+
70 74
 #define HAS_DRIVER(T) (    AXIS_DRIVER_TYPE_X(T)  || AXIS_DRIVER_TYPE_X2(T) \
71 75
                         || AXIS_DRIVER_TYPE_Y(T)  || AXIS_DRIVER_TYPE_Y2(T) \
72 76
                         || AXIS_DRIVER_TYPE_Z(T)  || AXIS_DRIVER_TYPE_Z2(T) || AXIS_DRIVER_TYPE_Z3(T) \
73
-                        || AXIS_DRIVER_TYPE_E0(T) || AXIS_DRIVER_TYPE_E1(T) \
74
-                        || AXIS_DRIVER_TYPE_E2(T) || AXIS_DRIVER_TYPE_E3(T) \
75
-                        || AXIS_DRIVER_TYPE_E4(T) || AXIS_DRIVER_TYPE_E5(T) )
77
+                        || HAS_E_DRIVER(T) )
76 78
 
77 79
 // Test for supported TMC drivers that require advanced configuration
78 80
 // Does not match standalone configurations

+ 6
- 6
Marlin/src/core/macros.h View File

@@ -118,24 +118,24 @@
118 118
   // Using GCC extensions, but Travis GCC version does not like it and gives
119 119
   //  "error: statement-expressions are not allowed outside functions nor in template-argument lists"
120 120
   #define NOLESS(v, n) \
121
-    do { \
121
+    do{ \
122 122
       __typeof__(n) _n = (n); \
123 123
       if (v < _n) v = _n; \
124
-    } while(0)
124
+    }while(0)
125 125
 
126 126
   #define NOMORE(v, n) \
127
-    do { \
127
+    do{ \
128 128
       __typeof__(n) _n = (n); \
129 129
       if (v > _n) v = _n; \
130
-    } while(0)
130
+    }while(0)
131 131
 
132 132
   #define LIMIT(v, n1, n2) \
133
-    do { \
133
+    do{ \
134 134
       __typeof__(n1) _n1 = (n1); \
135 135
       __typeof__(n2) _n2 = (n2); \
136 136
       if (v < _n1) v = _n1; \
137 137
       else if (v > _n2) v = _n2; \
138
-    } while(0)
138
+    }while(0)
139 139
 
140 140
 #endif
141 141
 

+ 2
- 2
Marlin/src/core/serial.h View File

@@ -184,5 +184,5 @@ void print_bin(const uint16_t val);
184 184
 
185 185
 void print_xyz(PGM_P const prefix, PGM_P const suffix, const float x, const float y, const float z);
186 186
 void print_xyz(PGM_P const prefix, PGM_P const suffix, const float xyz[]);
187
-#define SERIAL_POS(SUFFIX,VAR) do { print_xyz(PSTR("  " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); } while(0)
188
-#define SERIAL_XYZ(PREFIX,V...) do { print_xyz(PSTR(PREFIX), nullptr, V); } while(0)
187
+#define SERIAL_POS(SUFFIX,VAR) do { print_xyz(PSTR("  " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0)
188
+#define SERIAL_XYZ(PREFIX,V...) do { print_xyz(PSTR(PREFIX), nullptr, V); }while(0)

+ 5
- 7
Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp View File

@@ -752,16 +752,15 @@
752 752
       save_ubl_active_state_and_disable();  // No bed level correction so only raw data is obtained
753 753
       DEPLOY_PROBE();
754 754
 
755
-      uint8_t count = GRID_MAX_POINTS, current = 1;
755
+      uint8_t count = GRID_MAX_POINTS;
756 756
 
757 757
       do {
758
-        current = (GRID_MAX_POINTS) - count + 1;
759
-
760 758
         if (do_ubl_mesh_map) display_map(g29_map_type);
761 759
 
762
-        SERIAL_ECHOLNPAIR("\nProbing mesh point ", int(current), "/", int(GRID_MAX_POINTS), ".\n");
760
+        const int current = (GRID_MAX_POINTS) - count + 1;
761
+        SERIAL_ECHOLNPAIR("\nProbing mesh point ", current, "/", int(GRID_MAX_POINTS), ".\n");
763 762
         #if HAS_DISPLAY
764
-          ui.status_printf_P(0, PSTR(MSG_PROBING_MESH " %i/%i"), int(current), int(GRID_MAX_POINTS));
763
+          ui.status_printf_P(0, PSTR(MSG_PROBING_MESH " %i/%i"), current, int(GRID_MAX_POINTS));
765 764
         #endif
766 765
 
767 766
         #if HAS_LCD_MENU
@@ -1500,8 +1499,7 @@
1500 1499
                 DEBUG_ECHO_F(rx, 7);
1501 1500
                 DEBUG_CHAR(',');
1502 1501
                 DEBUG_ECHO_F(ry, 7);
1503
-                DEBUG_ECHOPGM(")   logical: ");
1504
-                DEBUG_CHAR('(');
1502
+                DEBUG_ECHOPGM(")   logical: (");
1505 1503
                 DEBUG_ECHO_F(LOGICAL_X_POSITION(rx), 7);
1506 1504
                 DEBUG_CHAR(',');
1507 1505
                 DEBUG_ECHO_F(LOGICAL_Y_POSITION(ry), 7);

+ 23
- 16
Marlin/src/feature/controllerfan.cpp View File

@@ -36,35 +36,37 @@ void controllerfan_update() {
36 36
   if (ELAPSED(ms, nextMotorCheck)) {
37 37
     nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s
38 38
 
39
+    const bool xory = X_ENABLE_READ() == X_ENABLE_ON || Y_ENABLE_READ() == Y_ENABLE_ON;
40
+
39 41
     // If any of the drivers or the bed are enabled...
40
-    if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON
42
+    if (xory || Z_ENABLE_READ() == Z_ENABLE_ON
41 43
       #if HAS_HEATED_BED
42 44
         || thermalManager.temp_bed.soft_pwm_amount > 0
43 45
       #endif
44 46
         #if HAS_X2_ENABLE
45
-          || X2_ENABLE_READ == X_ENABLE_ON
47
+          || X2_ENABLE_READ() == X_ENABLE_ON
46 48
         #endif
47 49
         #if HAS_Y2_ENABLE
48
-          || Y2_ENABLE_READ == Y_ENABLE_ON
50
+          || Y2_ENABLE_READ() == Y_ENABLE_ON
49 51
         #endif
50 52
         #if HAS_Z2_ENABLE
51
-          || Z2_ENABLE_READ == Z_ENABLE_ON
53
+          || Z2_ENABLE_READ() == Z_ENABLE_ON
52 54
         #endif
53 55
         #if HAS_Z3_ENABLE
54
-          || Z3_ENABLE_READ == Z_ENABLE_ON
56
+          || Z3_ENABLE_READ() == Z_ENABLE_ON
55 57
         #endif
56 58
         #if E_STEPPERS
57
-          || E0_ENABLE_READ == E_ENABLE_ON
59
+          || E0_ENABLE_READ() == E_ENABLE_ON
58 60
           #if E_STEPPERS > 1
59
-            || E1_ENABLE_READ == E_ENABLE_ON
61
+            || E1_ENABLE_READ() == E_ENABLE_ON
60 62
             #if E_STEPPERS > 2
61
-              || E2_ENABLE_READ == E_ENABLE_ON
63
+              || E2_ENABLE_READ() == E_ENABLE_ON
62 64
               #if E_STEPPERS > 3
63
-                || E3_ENABLE_READ == E_ENABLE_ON
65
+                || E3_ENABLE_READ() == E_ENABLE_ON
64 66
                 #if E_STEPPERS > 4
65
-                  || E4_ENABLE_READ == E_ENABLE_ON
67
+                  || E4_ENABLE_READ() == E_ENABLE_ON
66 68
                   #if E_STEPPERS > 5
67
-                    || E5_ENABLE_READ == E_ENABLE_ON
69
+                    || E5_ENABLE_READ() == E_ENABLE_ON
68 70
                   #endif // E_STEPPERS > 5
69 71
                 #endif // E_STEPPERS > 4
70 72
               #endif // E_STEPPERS > 3
@@ -76,12 +78,17 @@ void controllerfan_update() {
76 78
     }
77 79
 
78 80
     // Fan off if no steppers have been enabled for CONTROLLERFAN_SECS seconds
79
-    uint8_t speed = (!lastMotorOn || ELAPSED(ms, lastMotorOn + (CONTROLLERFAN_SECS) * 1000UL)) ? 0 : CONTROLLERFAN_SPEED;
80
-    controllerfan_speed = speed;
81
+    controllerfan_speed = (!lastMotorOn || ELAPSED(ms, lastMotorOn + (CONTROLLERFAN_SECS) * 1000UL)) ? 0 : (
82
+      #ifdef CONTROLLERFAN_SPEED_Z_ONLY
83
+        xory ? CONTROLLERFAN_SPEED : CONTROLLERFAN_SPEED_Z_ONLY
84
+      #else
85
+        CONTROLLERFAN_SPEED
86
+      #endif
87
+    );
81 88
 
82
-    // allows digital or PWM fan output to be used (see M42 handling)
83
-    WRITE(CONTROLLER_FAN_PIN, speed);
84
-    analogWrite(pin_t(CONTROLLER_FAN_PIN), speed);
89
+    // Allow digital or PWM fan output (see M42 handling)
90
+    WRITE(CONTROLLER_FAN_PIN, controllerfan_speed);
91
+    analogWrite(pin_t(CONTROLLER_FAN_PIN), controllerfan_speed);
85 92
   }
86 93
 }
87 94
 

+ 1
- 1
Marlin/src/feature/leds/leds.cpp View File

@@ -125,7 +125,7 @@ void LEDLights::set_color(const LEDColor &incol
125 125
     // If the pins can do PWM then their intensity will be set.
126 126
     #define UPDATE_RGBW(C,c) do { if (PWM_PIN(RGB_LED_##C##_PIN)) \
127 127
         analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \
128
-      else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); } while(0)
128
+      else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); }while(0)
129 129
     UPDATE_RGBW(R,r);
130 130
     UPDATE_RGBW(G,g);
131 131
     UPDATE_RGBW(B,b);

+ 5
- 3
Marlin/src/feature/leds/pca9632.cpp View File

@@ -137,13 +137,15 @@ void pca9632_set_led_color(const LEDColor &color) {
137 137
 }
138 138
 
139 139
 #if ENABLED(PCA9632_BUZZER)
140
-  void pca9632_buzz(uint16_t const f, uint16_t d) {
141
-    UNUSED(f); UNUSED(d);
140
+
141
+  void pca9632_buzz(const long duration, const uint16_t freq) {
142
+    UNUSED(duration); UNUSED(freq);
142 143
     uint8_t data[] = PCA9632_BUZZER_DATA;
143 144
     Wire.beginTransmission(I2C_ADDRESS(PCA9632_ADDRESS));
144 145
     Wire.write(data, sizeof(data));
145 146
     Wire.endTransmission();
146 147
   }
147
-#endif
148
+
149
+#endif // PCA9632_BUZZER
148 150
 
149 151
 #endif // PCA9632

+ 2
- 1
Marlin/src/feature/leds/pca9632.h View File

@@ -32,5 +32,6 @@ typedef LEDColor LEDColor;
32 32
 void pca9632_set_led_color(const LEDColor &color);
33 33
 
34 34
 #if ENABLED(PCA9632_BUZZER)
35
-  void pca9632_buzz(uint16_t const, uint16_t);
35
+  #include <stdint.h>
36
+  void pca9632_buzz(const long, const uint16_t);
36 37
 #endif

+ 15
- 2
Marlin/src/feature/pause.cpp View File

@@ -187,6 +187,9 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
187 187
       host_action_prompt_button(PSTR("Continue"));
188 188
       host_action_prompt_show();
189 189
     #endif
190
+    #if ENABLED(EXTENSIBLE_UI)
191
+      ExtUI::onStatusChanged(PSTR("Load Filament"));
192
+    #endif
190 193
     while (wait_for_user) {
191 194
       #if HAS_BUZZER
192 195
         filament_change_beep(max_beep_count);
@@ -239,6 +242,9 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
239 242
     #if ENABLED(HOST_PROMPT_SUPPORT)
240 243
       host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Continuous Purge Running..."), PSTR("Continue"));
241 244
     #endif
245
+    #if ENABLED(EXTENSIBLE_UI)
246
+      ExtUI::onStatusChanged(PSTR("Continuous Purge Running..."));
247
+    #endif
242 248
     for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
243 249
       do_pause_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
244 250
     wait_for_user = false;
@@ -353,8 +359,8 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
353 359
     planner.settings.retract_acceleration = saved_acceleration;
354 360
   #endif
355 361
 
356
-  // Disable extruders steppers for manual filament changing (only on boards that have separate ENABLE_PINS)
357
-  #if (E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN) || AXIS_DRIVER_TYPE_E0(TMC2660) || AXIS_DRIVER_TYPE_E1(TMC2660) || AXIS_DRIVER_TYPE_E2(TMC2660) || AXIS_DRIVER_TYPE_E3(TMC2660) || AXIS_DRIVER_TYPE_E4(TMC2660) || AXIS_DRIVER_TYPE_E5(TMC2660)
362
+  // Disable E steppers for manual change
363
+  #if HAS_E_STEPPER_ENABLE
358 364
     disable_e_stepper(active_extruder);
359 365
     safe_delay(100);
360 366
   #endif
@@ -517,6 +523,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
517 523
   #if ENABLED(HOST_PROMPT_SUPPORT)
518 524
     host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), PSTR("Continue"));
519 525
   #endif
526
+  #if ENABLED(EXTENSIBLE_UI)
527
+    ExtUI::onStatusChanged(PSTR("Nozzle Parked"));
528
+  #endif
520 529
   while (wait_for_user) {
521 530
     #if HAS_BUZZER
522 531
       filament_change_beep(max_beep_count);
@@ -538,6 +547,10 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
538 547
         host_prompt_do(PROMPT_USER_CONTINUE, PSTR("HeaterTimeout"), PSTR("Reheat"));
539 548
       #endif
540 549
 
550
+      #if ENABLED(EXTENSIBLE_UI)
551
+        ExtUI::onStatusChanged(PSTR("HeaterTimeout"));
552
+      #endif
553
+
541 554
       // Wait for LCD click or M108
542 555
       while (wait_for_user) idle(true);
543 556
 

+ 10
- 10
Marlin/src/feature/power.cpp View File

@@ -55,31 +55,31 @@ bool Power::is_power_needed() {
55 55
   #endif
56 56
 
57 57
   // If any of the drivers or the bed are enabled...
58
-  if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON
58
+  if (X_ENABLE_READ() == X_ENABLE_ON || Y_ENABLE_READ() == Y_ENABLE_ON || Z_ENABLE_READ() == Z_ENABLE_ON
59 59
     #if HAS_HEATED_BED
60 60
       || thermalManager.temp_bed.soft_pwm_amount > 0
61 61
     #endif
62 62
       #if HAS_X2_ENABLE
63
-        || X2_ENABLE_READ == X_ENABLE_ON
63
+        || X2_ENABLE_READ() == X_ENABLE_ON
64 64
       #endif
65 65
       #if HAS_Y2_ENABLE
66
-        || Y2_ENABLE_READ == Y_ENABLE_ON
66
+        || Y2_ENABLE_READ() == Y_ENABLE_ON
67 67
       #endif
68 68
       #if HAS_Z2_ENABLE
69
-        || Z2_ENABLE_READ == Z_ENABLE_ON
69
+        || Z2_ENABLE_READ() == Z_ENABLE_ON
70 70
       #endif
71 71
       #if E_STEPPERS
72
-        || E0_ENABLE_READ == E_ENABLE_ON
72
+        || E0_ENABLE_READ() == E_ENABLE_ON
73 73
         #if E_STEPPERS > 1
74
-          || E1_ENABLE_READ == E_ENABLE_ON
74
+          || E1_ENABLE_READ() == E_ENABLE_ON
75 75
           #if E_STEPPERS > 2
76
-            || E2_ENABLE_READ == E_ENABLE_ON
76
+            || E2_ENABLE_READ() == E_ENABLE_ON
77 77
             #if E_STEPPERS > 3
78
-              || E3_ENABLE_READ == E_ENABLE_ON
78
+              || E3_ENABLE_READ() == E_ENABLE_ON
79 79
               #if E_STEPPERS > 4
80
-                || E4_ENABLE_READ == E_ENABLE_ON
80
+                || E4_ENABLE_READ() == E_ENABLE_ON
81 81
                 #if E_STEPPERS > 5
82
-                  || E5_ENABLE_READ == E_ENABLE_ON
82
+                  || E5_ENABLE_READ() == E_ENABLE_ON
83 83
                 #endif // E_STEPPERS > 5
84 84
               #endif // E_STEPPERS > 4
85 85
             #endif // E_STEPPERS > 3

+ 19
- 1
Marlin/src/feature/power_loss_recovery.h View File

@@ -26,12 +26,16 @@
26 26
  */
27 27
 
28 28
 #include "../sd/cardreader.h"
29
-#include "../inc/MarlinConfigPre.h"
29
+#include "../inc/MarlinConfig.h"
30 30
 
31 31
 #if ENABLED(MIXING_EXTRUDER)
32 32
   #include "../feature/mixing.h"
33 33
 #endif
34 34
 
35
+#if !defined(POWER_LOSS_STATE) && PIN_EXISTS(POWER_LOSS)
36
+  #define POWER_LOSS_STATE HIGH
37
+#endif
38
+
35 39
 //#define DEBUG_POWER_LOSS_RECOVERY
36 40
 //#define SAVE_EACH_CMD_MODE
37 41
 //#define SAVE_INFO_INTERVAL_MS 0
@@ -110,6 +114,20 @@ class PrintJobRecovery {
110 114
 
111 115
     static void init();
112 116
 
117
+    static inline void setup() {
118
+      #if PIN_EXISTS(POWER_LOSS)
119
+        #if ENABLED(POWER_LOSS_PULL)
120
+          #if POWER_LOSS_STATE == LOW
121
+            SET_INPUT_PULLUP(POWER_LOSS_PIN);
122
+          #else
123
+            SET_INPUT_PULLDOWN(POWER_LOSS_PIN);
124
+          #endif
125
+        #else
126
+          SET_INPUT(POWER_LOSS_PIN);
127
+        #endif
128
+      #endif
129
+    }
130
+
113 131
     static bool enabled;
114 132
     static void enable(const bool onoff);
115 133
     static void changed();

+ 7
- 0
Marlin/src/feature/prusa_MMU2/mmu2.cpp View File

@@ -42,6 +42,10 @@ MMU2 mmu2;
42 42
   #include "../../feature/host_actions.h"
43 43
 #endif
44 44
 
45
+#if ENABLED(EXTENSIBLE_UI)
46
+  #include "../../lcd/extensible_ui/ui_api.h"
47
+#endif
48
+
45 49
 #define DEBUG_OUT ENABLED(MMU2_DEBUG)
46 50
 #include "../../core/debug_out.h"
47 51
 
@@ -711,6 +715,9 @@ void MMU2::filament_runout() {
711 715
       #if ENABLED(HOST_PROMPT_SUPPORT)
712 716
         host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), PSTR("Continue"));
713 717
       #endif
718
+      #if ENABLED(EXTENSIBLE_UI)
719
+        ExtUI::onStatusChanged(PSTR("MMU2 Eject Recover"));
720
+      #endif
714 721
       while (wait_for_user) idle();
715 722
       BUZZ(200, 404);
716 723
       BUZZ(200, 404);

+ 2
- 0
Marlin/src/feature/runout.h View File

@@ -249,6 +249,8 @@ class FilamentSensorBase {
249 249
               && (dual_x_carriage_mode == DXC_DUPLICATION_MODE || dual_x_carriage_mode == DXC_MIRRORED_MODE)
250 250
             #elif ENABLED(MULTI_NOZZLE_DUPLICATION)
251 251
               && extruder_duplication_enabled
252
+            #else
253
+              && false
252 254
             #endif
253 255
           #endif
254 256
         ) return runout_states;               // Any extruder

+ 1
- 1
Marlin/src/gcode/calibrate/G33.cpp View File

@@ -445,7 +445,7 @@ void GcodeSuite::G33() {
445 445
              _tower_results       = (_4p_calibration && towers_set) || probe_points >= 3,
446 446
              _opposite_results    = (_4p_calibration && !towers_set) || probe_points >= 3,
447 447
              _endstop_results     = probe_points != 1 && probe_points != -1 && probe_points != 0,
448
-             _angle_results       = probe_points >= 3  && towers_set;
448
+             _angle_results       = probe_points >= 3 && towers_set;
449 449
   static const char save_message[] PROGMEM = "Save with M500 and/or copy to Configuration.h";
450 450
   int8_t iterations = 0;
451 451
   float test_precision,

+ 1
- 1
Marlin/src/gcode/calibrate/G34_M422.cpp View File

@@ -284,7 +284,7 @@ void GcodeSuite::G34() {
284 284
     // Home Z after the alignment procedure
285 285
     process_subcommands_now_P(PSTR("G28 Z"));
286 286
 
287
-  } while(0);
287
+  }while(0);
288 288
 
289 289
   if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< G34");
290 290
 }

+ 7
- 0
Marlin/src/gcode/config/M43.cpp View File

@@ -42,6 +42,10 @@
42 42
   #include "../../feature/host_actions.h"
43 43
 #endif
44 44
 
45
+#if ENABLED(EXTENSIBLE_UI)
46
+  #include "../../lcd/extensible_ui/ui_api.h"
47
+#endif
48
+
45 49
 #ifndef GET_PIN_MAP_PIN_M43
46 50
   #define GET_PIN_MAP_PIN_M43(Q) GET_PIN_MAP_PIN(Q)
47 51
 #endif
@@ -329,6 +333,9 @@ void GcodeSuite::M43() {
329 333
       #if ENABLED(HOST_PROMPT_SUPPORT)
330 334
         host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), PSTR("Continue"));
331 335
       #endif
336
+      #if ENABLED(EXTENSIBLE_UI)
337
+        ExtUI::onStatusChanged(PSTR("M43 Wait Called"));
338
+      #endif
332 339
     #endif
333 340
 
334 341
     for (;;) {

+ 17
- 10
Marlin/src/gcode/control/M17_M18_M84.cpp View File

@@ -30,11 +30,21 @@
30 30
 #endif
31 31
 
32 32
 /**
33
- * M17: Enable power on all stepper motors
33
+ * M17: Enable stepper motors
34 34
  */
35 35
 void GcodeSuite::M17() {
36
-  LCD_MESSAGEPGM(MSG_NO_MOVE);
37
-  enable_all_steppers();
36
+  if (parser.seen("XYZE")) {
37
+    if (parser.seen('X')) enable_X();
38
+    if (parser.seen('Y')) enable_Y();
39
+    if (parser.seen('Z')) enable_Z();
40
+    #if HAS_E_STEPPER_ENABLE
41
+      if (parser.seen('E')) enable_e_steppers();
42
+    #endif
43
+  }
44
+  else {
45
+    LCD_MESSAGEPGM(MSG_NO_MOVE);
46
+    enable_all_steppers();
47
+  }
38 48
 }
39 49
 
40 50
 /**
@@ -45,20 +55,17 @@ void GcodeSuite::M18_M84() {
45 55
     stepper_inactive_time = parser.value_millis_from_seconds();
46 56
   }
47 57
   else {
48
-    bool all_axis = !(parser.seen('X') || parser.seen('Y') || parser.seen('Z') || parser.seen('E'));
49
-    if (all_axis) {
50
-      planner.finish_and_disable();
51
-    }
52
-    else {
58
+    if (parser.seen("XYZE")) {
53 59
       planner.synchronize();
54 60
       if (parser.seen('X')) disable_X();
55 61
       if (parser.seen('Y')) disable_Y();
56 62
       if (parser.seen('Z')) disable_Z();
57
-      // Only disable on boards that have separate ENABLE_PINS or another method for disabling the driver
58
-      #if (E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN) || AXIS_DRIVER_TYPE_E0(TMC2660) || AXIS_DRIVER_TYPE_E1(TMC2660) || AXIS_DRIVER_TYPE_E2(TMC2660) || AXIS_DRIVER_TYPE_E3(TMC2660) || AXIS_DRIVER_TYPE_E4(TMC2660) || AXIS_DRIVER_TYPE_E5(TMC2660)
63
+      #if HAS_E_STEPPER_ENABLE
59 64
         if (parser.seen('E')) disable_e_steppers();
60 65
       #endif
61 66
     }
67
+    else
68
+      planner.finish_and_disable();
62 69
 
63 70
     #if HAS_LCD_MENU && ENABLED(AUTO_BED_LEVELING_UBL)
64 71
       if (ubl.lcd_map_control) {

+ 1
- 1
Marlin/src/gcode/eeprom/M500-M504.cpp View File

@@ -52,7 +52,7 @@ void GcodeSuite::M502() {
52 52
    * M503: print settings currently in memory
53 53
    */
54 54
   void GcodeSuite::M503() {
55
-    (void)settings.report(parser.boolval('S', true));
55
+    (void)settings.report(!parser.boolval('S', true));
56 56
   }
57 57
 
58 58
 #endif // !DISABLE_M503

+ 4
- 0
Marlin/src/gcode/gcode.cpp View File

@@ -342,6 +342,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
342 342
         case 12: M12(); break;                                    // M12: Synchronize and optionally force a CLC set
343 343
       #endif
344 344
 
345
+      #if ENABLED(EXPECTED_PRINTER_CHECK)
346
+        case 16: M16(); break;                                    // M16: Expected printer check
347
+      #endif
348
+
345 349
       case 17: M17(); break;                                      // M17: Enable all stepper motors
346 350
 
347 351
       #if ENABLED(SDSUPPORT)

+ 5
- 0
Marlin/src/gcode/gcode.h View File

@@ -83,6 +83,7 @@
83 83
  * M8   - Turn flood coolant ON. (Requires COOLANT_CONTROL)
84 84
  * M9   - Turn coolant OFF. (Requires COOLANT_CONTROL)
85 85
  * M12  - Set up closed loop control system. (Requires EXTERNAL_CLOSED_LOOP_CONTROLLER)
86
+ * M16  - Expected printer check. (Requires EXPECTED_PRINTER_CHECK)
86 87
  * M17  - Enable/Power all stepper motors
87 88
  * M18  - Disable all stepper motors; same as M84
88 89
  * M20  - List SD card. (Requires SDSUPPORT)
@@ -472,6 +473,10 @@ private:
472 473
     static void M12();
473 474
   #endif
474 475
 
476
+  #if ENABLED(EXPECTED_PRINTER_CHECK)
477
+    static void M16();
478
+  #endif
479
+
475 480
   static void M17();
476 481
 
477 482
   static void M18_M84();

+ 40
- 0
Marlin/src/gcode/host/M16.cpp View File

@@ -0,0 +1,40 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../inc/MarlinConfigPre.h"
24
+
25
+#if ENABLED(EXPECTED_PRINTER_CHECK)
26
+
27
+#include "../gcode.h"
28
+#include "../../Marlin.h"
29
+
30
+/**
31
+ * M16: Expected Printer Check
32
+ */
33
+void GcodeSuite::M16() {
34
+
35
+  if (strcmp_P(parser.string_arg, PSTR(MACHINE_NAME)))
36
+    kill(PSTR(MSG_EXPECTED_PRINTER));
37
+
38
+}
39
+
40
+#endif

+ 3
- 0
Marlin/src/gcode/lcd/M0_M1.cpp View File

@@ -97,6 +97,9 @@ void GcodeSuite::M0_M1() {
97 97
   #if ENABLED(HOST_PROMPT_SUPPORT)
98 98
     host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M0/1 Break Called"), PSTR("Continue"));
99 99
   #endif
100
+  #if ENABLED(EXTENSIBLE_UI)
101
+    ExtUI::onStatusChanged(PSTR("M0/1 Break Called"));
102
+  #endif
100 103
 
101 104
   if (ms > 0) {
102 105
     ms += millis();  // wait until this time for a click

+ 3
- 0
Marlin/src/gcode/parser.cpp View File

@@ -225,6 +225,9 @@ void GCodeParser::parse(char *p) {
225 225
       case 810: case 811: case 812: case 813: case 814:
226 226
       case 815: case 816: case 817: case 818: case 819:
227 227
     #endif
228
+    #if ENABLED(EXPECTED_PRINTER_CHECK)
229
+      case 16:
230
+    #endif
228 231
     case 23: case 28: case 30: case 117: case 118: case 928: string_arg = p; return;
229 232
     default: break;
230 233
   }

+ 17
- 59
Marlin/src/inc/Conditionals_LCD.h View File

@@ -30,9 +30,9 @@
30 30
 
31 31
   #define DOGLCD
32 32
   #define IS_ULTIPANEL
33
-  #define DEFAULT_LCD_CONTRAST 90
34
-  #define LCD_CONTRAST_MIN 60
33
+  #define LCD_CONTRAST_MIN  60
35 34
   #define LCD_CONTRAST_MAX 140
35
+  #define LCD_CONTRAST_INIT 90
36 36
 
37 37
 #elif ENABLED(ZONESTAR_LCD)
38 38
 
@@ -65,23 +65,23 @@
65 65
   #if ENABLED(miniVIKI)
66 66
     #define LCD_CONTRAST_MIN      75
67 67
     #define LCD_CONTRAST_MAX     115
68
-    #define DEFAULT_LCD_CONTRAST  95
68
+    #define LCD_CONTRAST_INIT     95
69 69
     #define U8GLIB_ST7565_64128N
70 70
   #elif ENABLED(VIKI2)
71 71
     #define LCD_CONTRAST_MIN       0
72 72
     #define LCD_CONTRAST_MAX     255
73
-    #define DEFAULT_LCD_CONTRAST 140
73
+    #define LCD_CONTRAST_INIT    140
74 74
     #define U8GLIB_ST7565_64128N
75 75
   #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
76 76
     #define LCD_CONTRAST_MIN      90
77 77
     #define LCD_CONTRAST_MAX     130
78
-    #define DEFAULT_LCD_CONTRAST 110
78
+    #define LCD_CONTRAST_INIT    110
79 79
     #define U8GLIB_LM6059_AF
80 80
     #define SD_DETECT_INVERTED
81 81
   #elif ENABLED(AZSMZ_12864)
82 82
     #define LCD_CONTRAST_MIN     120
83 83
     #define LCD_CONTRAST_MAX     255
84
-    #define DEFAULT_LCD_CONTRAST 190
84
+    #define LCD_CONTRAST_INIT    190
85 85
     #define U8GLIB_ST7565_64128N
86 86
   #endif
87 87
 
@@ -128,17 +128,17 @@
128 128
 #elif ENABLED(MKS_MINI_12864)
129 129
 
130 130
   #define MINIPANEL
131
-  #define DEFAULT_LCD_CONTRAST 150
132
-  #define LCD_CONTRAST_MAX 255
131
+  #define LCD_CONTRAST_MAX  255
132
+  #define LCD_CONTRAST_INIT 150
133 133
 
134 134
 #elif ANY(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1)
135 135
 
136 136
   #define FYSETC_MINI_12864
137 137
   #define DOGLCD
138 138
   #define IS_ULTIPANEL
139
-  #define LCD_CONTRAST_MIN 0
140
-  #define LCD_CONTRAST_MAX 255
141
-  #define DEFAULT_LCD_CONTRAST 220
139
+  #define LCD_CONTRAST_MIN    0
140
+  #define LCD_CONTRAST_MAX  255
141
+  #define LCD_CONTRAST_INIT 220
142 142
   #define LED_COLORS_REDUCE_GREEN
143 143
   #if HAS_POWER_SWITCH && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1)
144 144
     #define LED_BACKLIGHT_TIMEOUT 10000
@@ -166,9 +166,9 @@
166 166
   #define IS_ULTIPANEL
167 167
   #define U8GLIB_SSD1309
168 168
   #define LCD_RESET_PIN LCD_PINS_D6 //  This controller need a reset pin
169
-  #define LCD_CONTRAST_MIN 0
170
-  #define LCD_CONTRAST_MAX 254
171
-  #define DEFAULT_LCD_CONTRAST 127
169
+  #define LCD_CONTRAST_MIN    0
170
+  #define LCD_CONTRAST_MAX  254
171
+  #define LCD_CONTRAST_INIT 127
172 172
   #define ENCODER_PULSES_PER_STEP 2
173 173
   #define ENCODER_STEPS_PER_MENU_ITEM 2
174 174
 
@@ -190,8 +190,8 @@
190 190
   #if ENABLED(MAKRPANEL)
191 191
     #define U8GLIB_ST7565_64128N
192 192
   #endif
193
-  #ifndef DEFAULT_LCD_CONTRAST
194
-    #define DEFAULT_LCD_CONTRAST 17
193
+  #ifndef LCD_CONTRAST_INIT
194
+    #define LCD_CONTRAST_INIT    17
195 195
   #endif
196 196
 #endif
197 197
 
@@ -368,7 +368,7 @@
368 368
 #endif
369 369
 
370 370
 // Extensible UI serial touch screens. (See src/lcd/extensible_ui)
371
-#if EITHER(MALYAN_LCD, DGUS_LCD)
371
+#if ANY(MALYAN_LCD, DGUS_LCD, LULZBOT_TOUCH_UI)
372 372
   #define IS_EXTUI
373 373
   #define EXTENSIBLE_UI
374 374
 #endif
@@ -382,22 +382,6 @@
382 382
 #define HAS_ADC_BUTTONS      ENABLED(ADC_KEYPAD)
383 383
 
384 384
 /**
385
- * Default LCD contrast for Graphical LCD displays
386
- */
387
-#define HAS_LCD_CONTRAST (HAS_GRAPHICAL_LCD && defined(DEFAULT_LCD_CONTRAST))
388
-#if HAS_LCD_CONTRAST
389
-  #ifndef LCD_CONTRAST_MIN
390
-    #define LCD_CONTRAST_MIN 0
391
-  #endif
392
-  #ifndef LCD_CONTRAST_MAX
393
-    #define LCD_CONTRAST_MAX 63
394
-  #endif
395
-  #ifndef DEFAULT_LCD_CONTRAST
396
-    #define DEFAULT_LCD_CONTRAST 32
397
-  #endif
398
-#endif
399
-
400
-/**
401 385
  * Extruders have some combination of stepper motors and hotends
402 386
  * so we separate these concepts into the defines:
403 387
  *
@@ -594,32 +578,6 @@
594 578
   #define INVERT_E_DIR false
595 579
 #endif
596 580
 
597
-#if ENABLED(HOST_ACTION_COMMANDS)
598
-  #ifndef ACTION_ON_PAUSE
599
-    #define ACTION_ON_PAUSE   "pause"
600
-  #endif
601
-  #ifndef ACTION_ON_RESUME
602
-    #define ACTION_ON_RESUME  "resume"
603
-  #endif
604
-  #ifndef ACTION_ON_PAUSED
605
-    #define ACTION_ON_PAUSED  "paused"
606
-  #endif
607
-  #ifndef ACTION_ON_RESUMED
608
-    #define ACTION_ON_RESUMED "resumed"
609
-  #endif
610
-  #ifndef ACTION_ON_CANCEL
611
-    #define ACTION_ON_CANCEL  "cancel"
612
-  #endif
613
-  #if ENABLED(G29_RETRY_AND_RECOVER)
614
-    #ifndef ACTION_ON_G29_RECOVER
615
-      #define ACTION_ON_G29_RECOVER "probe_rewipe"
616
-    #endif
617
-    #ifndef ACTION_ON_G29_FAILURE
618
-      #define ACTION_ON_G29_FAILURE "probe_failed"
619
-    #endif
620
-  #endif
621
-#endif
622
-
623 581
 #if ENABLED(SLIM_LCD_MENUS)
624 582
   #define BOOT_MARLIN_LOGO_SMALL
625 583
 #endif

+ 3
- 0
Marlin/src/inc/Conditionals_adv.h View File

@@ -99,3 +99,6 @@
99 99
     #define LED_USER_PRESET_BRIGHTNESS 255
100 100
   #endif
101 101
 #endif
102
+
103
+// Extensible UI pin mapping for RepRapDiscount
104
+#define TOUCH_UI_ULTIPANEL ENABLED(LULZBOT_TOUCH_UI) && ANY(AO_EXP1_PINMAP, AO_EXP2_PINMAP, CR10_TFT_PINMAP)

+ 38
- 2
Marlin/src/inc/Conditionals_post.h View File

@@ -247,6 +247,22 @@
247 247
 #endif
248 248
 
249 249
 /**
250
+ * Default LCD contrast for Graphical LCD displays
251
+ */
252
+#define HAS_LCD_CONTRAST defined(LCD_CONTRAST_INIT)
253
+#if HAS_LCD_CONTRAST
254
+  #ifndef DEFAULT_LCD_CONTRAST
255
+    #define DEFAULT_LCD_CONTRAST LCD_CONTRAST_INIT
256
+  #endif
257
+  #ifndef LCD_CONTRAST_MIN
258
+    #define LCD_CONTRAST_MIN 0
259
+  #endif
260
+  #ifndef LCD_CONTRAST_MAX
261
+    #define LCD_CONTRAST_MAX MAX(63, LCD_CONTRAST_INIT)
262
+  #endif
263
+#endif
264
+
265
+/**
250 266
  * Override here because this is set in Configuration_adv.h
251 267
  */
252 268
 #if HAS_LCD_MENU && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER)
@@ -927,6 +943,11 @@
927 943
   #endif
928 944
 #endif
929 945
 
946
+#define HAS_E_STEPPER_ENABLE (HAS_E_DRIVER(TMC2660) \
947
+  || ( E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != X_ENABLE_PIN   \
948
+    && E0_ENABLE_PIN != Y_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN ) \
949
+)
950
+
930 951
 // Endstops and bed probe
931 952
 #define _HAS_STOP(A,M) (PIN_EXISTS(A##_##M) && !IS_X2_ENDSTOP(A,M) && !IS_Y2_ENDSTOP(A,M) && !IS_Z2_OR_PROBE(A,M))
932 953
 #define HAS_X_MIN _HAS_STOP(X,MIN)
@@ -996,7 +1017,21 @@
996 1017
 #define HAS_AUTO_FAN_4 (HOTENDS > 4 && PIN_EXISTS(E4_AUTO_FAN))
997 1018
 #define HAS_AUTO_FAN_5 (HOTENDS > 5 && PIN_EXISTS(E5_AUTO_FAN))
998 1019
 #define HAS_AUTO_CHAMBER_FAN (HAS_TEMP_CHAMBER && PIN_EXISTS(CHAMBER_AUTO_FAN))
1020
+
999 1021
 #define HAS_AUTO_FAN (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3 || HAS_AUTO_FAN_4 || HAS_AUTO_FAN_5 || HAS_AUTO_CHAMBER_FAN)
1022
+#if HAS_AUTO_FAN
1023
+  #define AUTO_CHAMBER_IS_0 (CHAMBER_AUTO_FAN_PIN == E0_AUTO_FAN_PIN)
1024
+  #define AUTO_CHAMBER_IS_1 (CHAMBER_AUTO_FAN_PIN == E1_AUTO_FAN_PIN)
1025
+  #define AUTO_CHAMBER_IS_2 (CHAMBER_AUTO_FAN_PIN == E2_AUTO_FAN_PIN)
1026
+  #define AUTO_CHAMBER_IS_3 (CHAMBER_AUTO_FAN_PIN == E3_AUTO_FAN_PIN)
1027
+  #define AUTO_CHAMBER_IS_4 (CHAMBER_AUTO_FAN_PIN == E4_AUTO_FAN_PIN)
1028
+  #define AUTO_CHAMBER_IS_5 (CHAMBER_AUTO_FAN_PIN == E5_AUTO_FAN_PIN)
1029
+  #define AUTO_CHAMBER_IS_E (AUTO_CHAMBER_IS_0 || AUTO_CHAMBER_IS_1 || AUTO_CHAMBER_IS_2 || AUTO_CHAMBER_IS_3 || AUTO_CHAMBER_IS_4 || AUTO_CHAMBER_IS_5)
1030
+#endif
1031
+
1032
+#if !HAS_AUTO_CHAMBER_FAN || AUTO_CHAMBER_IS_E
1033
+  #undef AUTO_POWER_CHAMBER_FAN
1034
+#endif
1000 1035
 
1001 1036
 // Other fans
1002 1037
 #define HAS_FAN0 (PIN_EXISTS(FAN))
@@ -1029,7 +1064,8 @@
1029 1064
 #define HAS_KILL        (PIN_EXISTS(KILL))
1030 1065
 #define HAS_SUICIDE     (PIN_EXISTS(SUICIDE))
1031 1066
 #define HAS_PHOTOGRAPH  (PIN_EXISTS(PHOTOGRAPH))
1032
-#define HAS_BUZZER      (PIN_EXISTS(BEEPER) || ENABLED(LCD_USE_I2C_BUZZER) || ENABLED(PCA9632_BUZZER))
1067
+#define HAS_BUZZER      (PIN_EXISTS(BEEPER) || EITHER(LCD_USE_I2C_BUZZER, PCA9632_BUZZER))
1068
+#define USE_BEEPER      (HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER, PCA9632_BUZZER))
1033 1069
 #define HAS_CASE_LIGHT  (PIN_EXISTS(CASE_LIGHT) && ENABLED(CASE_LIGHT_ENABLE))
1034 1070
 
1035 1071
 // Digital control
@@ -1551,7 +1587,7 @@
1551 1587
   #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
1552 1588
     #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
1553 1589
   #endif
1554
-#else
1590
+#elif HAS_BUZZER
1555 1591
   #ifndef LCD_FEEDBACK_FREQUENCY_HZ
1556 1592
     #define LCD_FEEDBACK_FREQUENCY_HZ 5000
1557 1593
   #endif

+ 1
- 0
Marlin/src/inc/SanityCheck.h View File

@@ -1892,6 +1892,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
1892 1892
   + ENABLED(OVERLORD_OLED) \
1893 1893
   + ENABLED(DGUS_LCD) \
1894 1894
   + ENABLED(MALYAN_LCD) \
1895
+  + ENABLED(LULZBOT_TOUCH_UI) \
1895 1896
   + ENABLED(FSMC_GRAPHICAL_TFT)
1896 1897
   #error "Please select no more than one LCD controller option."
1897 1898
 #endif

+ 1
- 1
Marlin/src/inc/Version.h View File

@@ -51,7 +51,7 @@
51 51
    * here we define this default string as the date where the latest release
52 52
    * version was tagged.
53 53
    */
54
-  #define STRING_DISTRIBUTION_DATE "2019-08-08"
54
+  #define STRING_DISTRIBUTION_DATE "2019-08-21"
55 55
 
56 56
   /**
57 57
    * Required minimum Configuration.h and Configuration_adv.h file versions.

+ 1
- 1
Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp View File

@@ -877,7 +877,7 @@ static int pf_bsearch_cb_comp_hd4map_pgm(void *userdata, size_t idx, void * data
877 877
   return hd44780_charmap_compare(&localval, (hd44780_charmap_t *)data_pin);
878 878
 }
879 879
 
880
-void lcd_moveto(const uint8_t col, const uint8_t row) { lcd.setCursor(col, row); }
880
+void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) { lcd.setCursor(col, row); }
881 881
 
882 882
 void lcd_put_int(const int i) { lcd.print(i); }
883 883
 

+ 91
- 91
Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp View File

@@ -269,7 +269,7 @@ void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARS
269 269
 
270 270
   #endif // LCD_PROGRESS_BAR
271 271
 
272
-  #if ENABLED(SDSUPPORT)
272
+  #if ENABLED(SDSUPPORT) && HAS_LCD_MENU
273 273
 
274 274
     // CHARSET_MENU
275 275
     const static PROGMEM byte refresh[8] = {
@@ -319,7 +319,7 @@ void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARS
319 319
       #endif
320 320
         {
321 321
           createChar_P(LCD_STR_UPLEVEL[0], uplevel);
322
-          #if ENABLED(SDSUPPORT)
322
+          #if ENABLED(SDSUPPORT) && HAS_LCD_MENU
323 323
             // SD Card sub-menu special characters
324 324
             createChar_P(LCD_STR_REFRESH[0], refresh);
325 325
             createChar_P(LCD_STR_FOLDER[0], folder);
@@ -360,23 +360,48 @@ void MarlinUI::init_lcd() {
360 360
   lcd.clear();
361 361
 }
362 362
 
363
+bool MarlinUI::detected() {
364
+  return true
365
+    #if EITHER(LCD_I2C_TYPE_MCP23017, LCD_I2C_TYPE_MCP23008) && defined(DETECT_DEVICE)
366
+      && lcd.LcdDetected() == 1
367
+    #endif
368
+  ;
369
+}
370
+
371
+#if HAS_SLOW_BUTTONS
372
+  uint8_t MarlinUI::read_slow_buttons() {
373
+    #if ENABLED(LCD_I2C_TYPE_MCP23017)
374
+      // Reading these buttons this is likely to be too slow to call inside interrupt context
375
+      // so they are called during normal lcd_update
376
+      uint8_t slow_bits = lcd.readButtons()
377
+        #if !BUTTON_EXISTS(ENC)
378
+          << B_I2C_BTN_OFFSET
379
+        #endif
380
+      ;
381
+      #if ENABLED(LCD_I2C_VIKI)
382
+        if ((slow_bits & (B_MI | B_RI)) && PENDING(millis(), next_button_update_ms)) // LCD clicked
383
+          slow_bits &= ~(B_MI | B_RI); // Disable LCD clicked buttons if screen is updated
384
+      #endif // LCD_I2C_VIKI
385
+      return slow_bits;
386
+    #endif // LCD_I2C_TYPE_MCP23017
387
+  }
388
+#endif
389
+
363 390
 void MarlinUI::clear_lcd() { lcd.clear(); }
364 391
 
365 392
 #if ENABLED(SHOW_BOOTSCREEN)
366 393
 
367
-  void lcd_erase_line(const int16_t line) {
394
+  void lcd_erase_line(const lcd_uint_t line) {
368 395
     lcd_moveto(0, line);
369 396
     for (uint8_t i = LCD_WIDTH + 1; --i;)
370 397
       lcd_put_wchar(' ');
371 398
   }
372 399
 
373 400
   // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line
374
-  void lcd_scroll(const uint8_t col, const uint8_t line, PGM_P const text, const uint8_t len, const int16_t time) {
401
+  void lcd_scroll(const lcd_uint_t col, const lcd_uint_t line, PGM_P const text, const uint8_t len, const int16_t time) {
375 402
     uint8_t slen = utf8_strlen_P(text);
376 403
     if (slen < len) {
377
-      // Fits into,
378
-      lcd_moveto(col, line);
379
-      lcd_put_u8str_max_P(text, len);
404
+      lcd_put_u8str_max_P(col, line, text, len);
380 405
       for (; slen < len; ++slen) lcd_put_wchar(' ');
381 406
       safe_delay(time);
382 407
     }
@@ -385,11 +410,8 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
385 410
       int dly = time / _MAX(slen, 1);
386 411
       for (uint8_t i = 0; i <= slen; i++) {
387 412
 
388
-        // Go to the correct place
389
-        lcd_moveto(col, line);
390
-
391
-        // Print the text
392
-        lcd_put_u8str_max_P(p, len);
413
+        // Print the text at the correct place
414
+        lcd_put_u8str_max_P(col, line, p, len);
393 415
 
394 416
         // Fill with spaces
395 417
         for (uint8_t ix = slen - i; ix < len; ++ix) lcd_put_wchar(' ');
@@ -406,9 +428,9 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
406 428
 
407 429
   static void logo_lines(PGM_P const extra) {
408 430
     int16_t indent = (LCD_WIDTH - 8 - utf8_strlen_P(extra)) / 2;
409
-    lcd_moveto(indent, 0); lcd_put_wchar('\x00'); lcd_put_u8str_P(PSTR( "------" ));  lcd_put_wchar('\x01');
410
-    lcd_moveto(indent, 1);                        lcd_put_u8str_P(PSTR("|Marlin|"));  lcd_put_u8str_P(extra);
411
-    lcd_moveto(indent, 2); lcd_put_wchar('\x02'); lcd_put_u8str_P(PSTR( "------" ));  lcd_put_wchar('\x03');
431
+    lcd_put_wchar(indent, 0, '\x00'); lcd_put_u8str_P(PSTR( "------" ));  lcd_put_wchar('\x01');
432
+    lcd_put_u8str_P(indent, 1, PSTR("|Marlin|"));  lcd_put_u8str_P(extra);
433
+    lcd_put_wchar(indent, 2, '\x02'); lcd_put_u8str_P(PSTR( "------" ));  lcd_put_wchar('\x03');
412 434
   }
413 435
 
414 436
   void MarlinUI::show_bootscreen() {
@@ -420,8 +442,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
420 442
     #define CENTER_OR_SCROLL(STRING,DELAY) \
421 443
       lcd_erase_line(3); \
422 444
       if (utf8_strlen(STRING) <= LCD_WIDTH) { \
423
-        lcd_moveto((LCD_WIDTH - utf8_strlen_P(PSTR(STRING))) / 2, 3); \
424
-        lcd_put_u8str_P(PSTR(STRING)); \
445
+        lcd_put_u8str_P((LCD_WIDTH - utf8_strlen_P(PSTR(STRING))) / 2, 3, PSTR(STRING)); \
425 446
         safe_delay(DELAY); \
426 447
       } \
427 448
       else { \
@@ -491,16 +512,12 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
491 512
 #endif // SHOW_BOOTSCREEN
492 513
 
493 514
 void MarlinUI::draw_kill_screen() {
494
-  lcd_moveto(0, 0);
495
-  lcd_put_u8str(status_message);
496
-  #if LCD_HEIGHT < 4
497
-    lcd_moveto(0, 2);
498
-  #else
499
-    lcd_moveto(0, 2);
500
-    lcd_put_u8str_P(PSTR(MSG_HALTED));
501
-    lcd_moveto(0, 3);
515
+  lcd_put_u8str(0, 0, status_message);
516
+  lcd_uint_t y = 2;
517
+  #if LCD_HEIGHT >= 4
518
+    lcd_put_u8str_P(0, y++, PSTR(MSG_HALTED));
502 519
   #endif
503
-  lcd_put_u8str_P(PSTR(MSG_PLEASE_RESET));
520
+  lcd_put_u8str_P(0, y, PSTR(MSG_PLEASE_RESET));
504 521
 }
505 522
 
506 523
 //
@@ -859,8 +876,7 @@ void MarlinUI::draw_status_screen() {
859 876
 
860 877
     #if LCD_HEIGHT > 3
861 878
 
862
-      lcd_moveto(0, 2);
863
-      lcd_put_wchar(LCD_STR_FEEDRATE[0]);
879
+      lcd_put_wchar(0, 2, LCD_STR_FEEDRATE[0]);
864 880
       lcd_put_u8str(i16tostr3(feedrate_percentage));
865 881
       lcd_put_wchar('%');
866 882
 
@@ -868,8 +884,7 @@ void MarlinUI::draw_status_screen() {
868 884
       duration_t elapsed = print_job_timer.duration();
869 885
       const uint8_t len = elapsed.toDigital(buffer),
870 886
                     timepos = LCD_WIDTH - len - 1;
871
-      lcd_moveto(timepos, 2);
872
-      lcd_put_wchar(LCD_STR_CLOCK[0]);
887
+      lcd_put_wchar(timepos, 2, LCD_STR_CLOCK[0]);
873 888
       lcd_put_u8str(buffer);
874 889
 
875 890
       #if LCD_WIDTH >= 20
@@ -918,8 +933,7 @@ void MarlinUI::draw_status_screen() {
918 933
     _draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position[Z_AXIS])), blink);
919 934
 
920 935
     #if HAS_LEVELING && (HOTENDS > 1 || !HAS_HEATED_BED)
921
-      lcd_moveto(LCD_WIDTH - 1, 0);
922
-      lcd_put_wchar(planner.leveling_active || blink ? '_' : ' ');
936
+      lcd_put_wchar(LCD_WIDTH - 1, 0, planner.leveling_active || blink ? '_' : ' ');
923 937
     #endif
924 938
 
925 939
     // ========== Line 2 ==========
@@ -934,8 +948,7 @@ void MarlinUI::draw_status_screen() {
934 948
       _draw_bed_status(blink);
935 949
     #endif
936 950
 
937
-    lcd_moveto(LCD_WIDTH - 9, 1);
938
-    lcd_put_wchar(LCD_STR_FEEDRATE[0]);
951
+    lcd_put_wchar(LCD_WIDTH - 9, 1, LCD_STR_FEEDRATE[0]);
939 952
     lcd_put_u8str(i16tostr3(feedrate_percentage));
940 953
     lcd_put_wchar('%');
941 954
 
@@ -1006,8 +1019,7 @@ void MarlinUI::draw_status_screen() {
1006 1019
 
1007 1020
   void draw_menu_item(const bool sel, const uint8_t row, PGM_P pstr, const char pre_char, const char post_char) {
1008 1021
     uint8_t n = LCD_WIDTH - 2;
1009
-    lcd_moveto(0, row);
1010
-    lcd_put_wchar(sel ? pre_char : ' ');
1022
+    lcd_put_wchar(0, row, sel ? pre_char : ' ');
1011 1023
     n -= lcd_put_u8str_max_P(pstr, n);
1012 1024
     for (; n; --n) lcd_put_wchar(' ');
1013 1025
     lcd_put_wchar(post_char);
@@ -1015,8 +1027,7 @@ void MarlinUI::draw_status_screen() {
1015 1027
 
1016 1028
   void _draw_menu_item_edit(const bool sel, const uint8_t row, PGM_P pstr, const char* const data, const bool pgm) {
1017 1029
     uint8_t n = LCD_WIDTH - 2 - (pgm ? utf8_strlen_P(data) : utf8_strlen(data));
1018
-    lcd_moveto(0, row);
1019
-    lcd_put_wchar(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
1030
+    lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
1020 1031
     n -= lcd_put_u8str_max_P(pstr, n);
1021 1032
     lcd_put_wchar(':');
1022 1033
     for (; n; --n) lcd_put_wchar(' ');
@@ -1026,14 +1037,12 @@ void MarlinUI::draw_status_screen() {
1026 1037
   void draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
1027 1038
     ui.encoder_direction_normal();
1028 1039
 
1029
-    lcd_moveto(0, 1);
1030
-    lcd_put_u8str_P(pstr);
1040
+    lcd_put_u8str_P(0, 1, pstr);
1031 1041
     if (value != nullptr) {
1032 1042
       lcd_put_wchar(':');
1033 1043
       int len = utf8_strlen(value);
1034
-      const uint8_t valrow = (utf8_strlen_P(pstr) + 1 + len + 1) > (LCD_WIDTH - 2) ? 2 : 1;   // Value on the next row if it won't fit
1035
-      lcd_moveto((LCD_WIDTH - 1) - (len + 1), valrow);                                        // Right-justified, padded by spaces
1036
-      lcd_put_wchar(' ');                                                                     // Overwrite char if value gets shorter
1044
+      const lcd_uint_t valrow = (utf8_strlen_P(pstr) + 1 + len + 1) > (LCD_WIDTH - 2) ? 2 : 1;   // Value on the next row if it won't fit
1045
+      lcd_put_wchar((LCD_WIDTH - 1) - (len + 1), valrow, ' ');                                   // Right-justified, padded, add a leading space
1037 1046
       lcd_put_u8str(value);
1038 1047
     }
1039 1048
   }
@@ -1051,8 +1060,7 @@ void MarlinUI::draw_status_screen() {
1051 1060
     void draw_sd_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) {
1052 1061
       UNUSED(pstr);
1053 1062
 
1054
-      lcd_moveto(0, row);
1055
-      lcd_put_wchar(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
1063
+      lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
1056 1064
       constexpr uint8_t maxlen = LCD_WIDTH - 2;
1057 1065
       uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
1058 1066
       for (; n; --n) lcd_put_wchar(' ');
@@ -1063,7 +1071,7 @@ void MarlinUI::draw_status_screen() {
1063 1071
 
1064 1072
   #if ENABLED(LCD_HAS_STATUS_INDICATORS)
1065 1073
 
1066
-    static void MarlinUI::update_indicators() {
1074
+    void MarlinUI::update_indicators() {
1067 1075
       // Set the LEDS - referred to as backlights by the LiquidTWI2 library
1068 1076
       static uint8_t ledsprev = 0;
1069 1077
       uint8_t leds = 0;
@@ -1144,9 +1152,9 @@ void MarlinUI::draw_status_screen() {
1144 1152
     } custom_char;
1145 1153
 
1146 1154
     typedef struct {
1147
-      uint8_t column, row,
1148
-              x_pixel_offset, y_pixel_offset,
1149
-              x_pixel_mask;
1155
+      lcd_uint_t column, row,
1156
+                 x_pixel_offset, y_pixel_offset;
1157
+      uint8_t x_pixel_mask;
1150 1158
     } coordinate;
1151 1159
 
1152 1160
     void add_edges_to_custom_char(custom_char &custom, const coordinate &ul, const coordinate &lr, const coordinate &brc, const uint8_t cell_location);
@@ -1174,22 +1182,21 @@ void MarlinUI::draw_status_screen() {
1174 1182
       return ret_val;
1175 1183
     }
1176 1184
 
1177
-    inline coordinate pixel_location(const uint8_t x, const uint8_t y) { return pixel_location((int16_t)x, (int16_t)y); }
1185
+    inline coordinate pixel_location(const lcd_uint_t x, const lcd_uint_t y) { return pixel_location((int16_t)x, (int16_t)y); }
1178 1186
 
1179
-    void prep_and_put_map_char(custom_char &chrdata, const coordinate &ul, const coordinate &lr, const coordinate &brc, const uint8_t cl, const char c, const uint8_t x, const uint8_t y) {
1187
+    void prep_and_put_map_char(custom_char &chrdata, const coordinate &ul, const coordinate &lr, const coordinate &brc, const uint8_t cl, const char c, const lcd_uint_t x, const lcd_uint_t y) {
1180 1188
       add_edges_to_custom_char(chrdata, ul, lr, brc, cl);
1181 1189
       lcd.createChar(c, (uint8_t*)&chrdata);
1182
-      lcd_moveto(x, y);
1183
-      lcd_put_wchar(c);
1190
+      lcd_put_wchar(x, y, c);
1184 1191
     }
1185 1192
 
1186
-    void MarlinUI::ubl_plot(const uint8_t x, const uint8_t inverted_y) {
1193
+    void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) {
1187 1194
 
1188 1195
       #if LCD_WIDTH >= 20
1189 1196
         #define _LCD_W_POS 12
1190 1197
         #define _PLOT_X 1
1191 1198
         #define _MAP_X 3
1192
-        #define _LABEL(C,X,Y) lcd_moveto(X, Y); lcd_put_u8str(C)
1199
+        #define _LABEL(C,X,Y) lcd_put_u8str(X, Y, C)
1193 1200
         #define _XLABEL(X,Y) _LABEL("X:",X,Y)
1194 1201
         #define _YLABEL(X,Y) _LABEL("Y:",X,Y)
1195 1202
         #define _ZLABEL(X,Y) _LABEL("Z:",X,Y)
@@ -1197,7 +1204,7 @@ void MarlinUI::draw_status_screen() {
1197 1204
         #define _LCD_W_POS 8
1198 1205
         #define _PLOT_X 0
1199 1206
         #define _MAP_X 1
1200
-        #define _LABEL(X,Y,C) lcd_moveto(X, Y); lcd_put_wchar(C)
1207
+        #define _LABEL(X,Y,C) lcd_put_wchar(X, Y, C)
1201 1208
         #define _XLABEL(X,Y) _LABEL('X',X,Y)
1202 1209
         #define _YLABEL(X,Y) _LABEL('Y',X,Y)
1203 1210
         #define _ZLABEL(X,Y) _LABEL('Z',X,Y)
@@ -1209,10 +1216,10 @@ void MarlinUI::draw_status_screen() {
1209 1216
          * Show X and Y positions
1210 1217
          */
1211 1218
         _XLABEL(_PLOT_X, 0);
1212
-        lcd_put_u8str(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x]))));
1219
+        lcd_put_u8str(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
1213 1220
 
1214 1221
         _YLABEL(_LCD_W_POS, 0);
1215
-        lcd_put_u8str(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[inverted_y]))));
1222
+        lcd_put_u8str(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
1216 1223
 
1217 1224
         lcd_moveto(_PLOT_X, 0);
1218 1225
 
@@ -1220,13 +1227,13 @@ void MarlinUI::draw_status_screen() {
1220 1227
 
1221 1228
         coordinate upper_left, lower_right, bottom_right_corner;
1222 1229
         custom_char new_char;
1223
-        uint8_t i, j, k, l, m, n, n_rows, n_cols, y,
1224
-                bottom_line, right_edge,
1225
-                x_map_pixels, y_map_pixels,
1226
-                pixels_per_x_mesh_pnt, pixels_per_y_mesh_pnt,
1227
-                suppress_x_offset = 0, suppress_y_offset = 0;
1230
+        uint8_t i, n, n_rows, n_cols;
1231
+        lcd_uint_t j, k, l, m, bottom_line, right_edge,
1232
+                   x_map_pixels, y_map_pixels,
1233
+                   pixels_per_x_mesh_pnt, pixels_per_y_mesh_pnt,
1234
+                   suppress_x_offset = 0, suppress_y_offset = 0;
1228 1235
 
1229
-        y = GRID_MAX_POINTS_Y - inverted_y - 1;
1236
+        const uint8_t y_plot_inv = (GRID_MAX_POINTS_Y - 1) - y_plot;
1230 1237
 
1231 1238
         upper_left.column  = 0;
1232 1239
         upper_left.row     = 0;
@@ -1261,17 +1268,13 @@ void MarlinUI::draw_status_screen() {
1261 1268
         n_cols = right_edge / (HD44780_CHAR_WIDTH) + 1;
1262 1269
 
1263 1270
         for (i = 0; i < n_cols; i++) {
1264
-          lcd_moveto(i, 0);
1265
-          lcd_put_wchar(CHAR_LINE_TOP);                                     // Box Top line
1266
-          lcd_moveto(i, n_rows - 1);
1267
-          lcd_put_wchar(CHAR_LINE_BOT);                                     // Box Bottom line
1271
+          lcd_put_wchar(i, 0, CHAR_LINE_TOP);                               // Box Top line
1272
+          lcd_put_wchar(i, n_rows - 1, CHAR_LINE_BOT);                      // Box Bottom line
1268 1273
         }
1269 1274
 
1270 1275
         for (j = 0; j < n_rows; j++) {
1271
-          lcd_moveto(0, j);
1272
-          lcd_put_wchar(CHAR_EDGE_L);                                       // Box Left edge
1273
-          lcd_moveto(n_cols - 1, j);
1274
-          lcd_put_wchar(CHAR_EDGE_R);                                       // Box Right edge
1276
+          lcd_put_wchar(0, j, CHAR_EDGE_L);                                 // Box Left edge
1277
+          lcd_put_wchar(n_cols - 1, j, CHAR_EDGE_R);                        // Box Right edge
1275 1278
         }
1276 1279
 
1277 1280
         /**
@@ -1281,10 +1284,8 @@ void MarlinUI::draw_status_screen() {
1281 1284
         k = pixels_per_y_mesh_pnt * (GRID_MAX_POINTS_Y) + 2;
1282 1285
         l = (HD44780_CHAR_HEIGHT) * n_rows;
1283 1286
         if (l > k && l - k >= (HD44780_CHAR_HEIGHT) / 2) {
1284
-          lcd_moveto(0, n_rows - 1);                                        // Box Left edge
1285
-          lcd_put_wchar(' ');
1286
-          lcd_moveto(n_cols - 1, n_rows - 1);                               // Box Right edge
1287
-          lcd_put_wchar(' ');
1287
+          lcd_put_wchar(0, n_rows - 1, ' ');                                // Box Left edge
1288
+          lcd_put_wchar(n_cols - 1, n_rows - 1, ' ');                       // Box Right edge
1288 1289
         }
1289 1290
 
1290 1291
         clear_custom_char(&new_char);
@@ -1310,12 +1311,12 @@ void MarlinUI::draw_status_screen() {
1310 1311
           new_char.custom_char_bits[j] = (uint8_t)_BV(i);                   // Char #3 is used for the box right edge
1311 1312
         lcd.createChar(CHAR_EDGE_R, (uint8_t*)&new_char);
1312 1313
 
1313
-        i = x * pixels_per_x_mesh_pnt - suppress_x_offset;
1314
-        j = y * pixels_per_y_mesh_pnt - suppress_y_offset;
1314
+        i = x_plot * pixels_per_x_mesh_pnt - suppress_x_offset;
1315
+        j = y_plot_inv * pixels_per_y_mesh_pnt - suppress_y_offset;
1315 1316
         upper_left = pixel_location(i, j);
1316 1317
 
1317
-        k = (x + 1) * pixels_per_x_mesh_pnt - 1 - suppress_x_offset;
1318
-        l = (y + 1) * pixels_per_y_mesh_pnt - 1 - suppress_y_offset;
1318
+        k = (x_plot + 1) * pixels_per_x_mesh_pnt - 1 - suppress_x_offset;
1319
+        l = (y_plot_inv + 1) * pixels_per_y_mesh_pnt - 1 - suppress_y_offset;
1319 1320
         lower_right = pixel_location(k, l);
1320 1321
 
1321 1322
         bottom_right_corner = pixel_location(x_map_pixels, y_map_pixels);
@@ -1327,7 +1328,7 @@ void MarlinUI::draw_status_screen() {
1327 1328
          */
1328 1329
 
1329 1330
         clear_custom_char(&new_char);
1330
-        const uint8_t ypix = _MIN(upper_left.y_pixel_offset + pixels_per_y_mesh_pnt, HD44780_CHAR_HEIGHT);
1331
+        const lcd_uint_t ypix = _MIN(upper_left.y_pixel_offset + pixels_per_y_mesh_pnt, HD44780_CHAR_HEIGHT);
1331 1332
         for (j = upper_left.y_pixel_offset; j < ypix; j++) {
1332 1333
           i = upper_left.x_pixel_mask;
1333 1334
           for (k = 0; k < pixels_per_x_mesh_pnt; k++) {
@@ -1398,11 +1399,10 @@ void MarlinUI::draw_status_screen() {
1398 1399
       /**
1399 1400
        * Print plot position
1400 1401
        */
1401
-      lcd_moveto(_LCD_W_POS, 0);
1402
-      lcd_put_wchar('(');
1403
-      lcd_put_u8str(ui8tostr3(x));
1402
+      lcd_put_wchar(_LCD_W_POS, 0, '(');
1403
+      lcd_put_u8str(ui8tostr3(x_plot));
1404 1404
       lcd_put_wchar(',');
1405
-      lcd_put_u8str(ui8tostr3(inverted_y));
1405
+      lcd_put_u8str(ui8tostr3(y_plot));
1406 1406
       lcd_put_wchar(')');
1407 1407
 
1408 1408
       #if LCD_HEIGHT <= 3   // 16x2 or 20x2 display
@@ -1411,8 +1411,8 @@ void MarlinUI::draw_status_screen() {
1411 1411
          * Print Z values
1412 1412
          */
1413 1413
         _ZLABEL(_LCD_W_POS, 1);
1414
-        if (!isnan(ubl.z_values[x][inverted_y]))
1415
-          lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1414
+        if (!isnan(ubl.z_values[x_plot][y_plot]))
1415
+          lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot]));
1416 1416
         else
1417 1417
           lcd_put_u8str_P(PSTR(" -----"));
1418 1418
 
@@ -1422,16 +1422,16 @@ void MarlinUI::draw_status_screen() {
1422 1422
          * Show all values at right of screen
1423 1423
          */
1424 1424
         _XLABEL(_LCD_W_POS, 1);
1425
-        lcd_put_u8str(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x]))));
1425
+        lcd_put_u8str(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
1426 1426
         _YLABEL(_LCD_W_POS, 2);
1427
-        lcd_put_u8str(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[inverted_y]))));
1427
+        lcd_put_u8str(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
1428 1428
 
1429 1429
         /**
1430 1430
          * Show the location value
1431 1431
          */
1432 1432
         _ZLABEL(_LCD_W_POS, 3);
1433
-        if (!isnan(ubl.z_values[x][inverted_y]))
1434
-          lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1433
+        if (!isnan(ubl.z_values[x_plot][y_plot]))
1434
+          lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot]));
1435 1435
         else
1436 1436
           lcd_put_u8str_P(PSTR(" -----"));
1437 1437
 

+ 5
- 1
Marlin/src/lcd/dogm/HAL_LCD_com_defines.h View File

@@ -40,10 +40,14 @@
40 40
     #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_std_sw_spi_fn
41 41
     #define U8G_COM_ST7920_HAL_HW_SPI u8g_com_stm32duino_hw_spi_fn
42 42
   #elif defined(ARDUINO_ARCH_STM32)
43
+    uint8_t u8g_com_arduino_std_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
43 44
     #define U8G_COM_HAL_SW_SPI_FN u8g_com_arduino_std_sw_spi_fn
45
+    uint8_t u8g_com_stm32duino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
44 46
     #define U8G_COM_HAL_HW_SPI_FN u8g_com_stm32duino_hw_spi_fn
47
+    uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
45 48
     #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_arduino_st7920_spi_fn
46
-    #define U8G_COM_ST7920_HAL_HW_SPI u8g_com_stm32duino_hw_spi_fn
49
+    uint8_t u8g_com_arduino_st7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
50
+    #define U8G_COM_ST7920_HAL_HW_SPI u8g_com_arduino_st7920_hw_spi_fn
47 51
   #elif defined(__AVR__)
48 52
     uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
49 53
     #define U8G_COM_HAL_SW_SPI_FN  u8g_com_HAL_AVR_sw_sp_fn

+ 397
- 2
Marlin/src/lcd/dogm/dogm_Bootscreen.h View File

@@ -35,7 +35,7 @@
35 35
   #include "../../../_Bootscreen.h"
36 36
 
37 37
   #ifndef CUSTOM_BOOTSCREEN_BMP_BYTEWIDTH
38
-    #define CUSTOM_BOOTSCREEN_BMP_BYTEWIDTH ((CUSTOM_BOOTSCREEN_BMPWIDTH + 7) / 8)
38
+    #define CUSTOM_BOOTSCREEN_BMP_BYTEWIDTH CEILING(CUSTOM_BOOTSCREEN_BMPWIDTH, 8)
39 39
   #endif
40 40
   #ifndef CUSTOM_BOOTSCREEN_BMPHEIGHT
41 41
     #define CUSTOM_BOOTSCREEN_BMPHEIGHT (sizeof(custom_start_bmp) / (CUSTOM_BOOTSCREEN_BMP_BYTEWIDTH))
@@ -69,6 +69,142 @@
69 69
     B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111000
70 70
   };
71 71
 
72
+  #if ENABLED(BOOT_MARLIN_LOGO_ANIMATED)
73
+
74
+    const unsigned char start_bmp1[] PROGMEM = {
75
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
76
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
77
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
78
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
79
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,
80
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,
81
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,
82
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
83
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
84
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,
85
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,
86
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,
87
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,
88
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,
89
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,
90
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,
91
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,
92
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
93
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111000
94
+    };
95
+
96
+    const unsigned char start_bmp2[] PROGMEM = {
97
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
98
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
99
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
100
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
101
+      B10000011,B11001111,B00000000,B00000000,B00000000,B00000000,B00111111,
102
+      B10000111,B11111111,B10000000,B00000000,B00000000,B00000000,B00011111,
103
+      B10000110,B01111001,B10000000,B00000000,B00000000,B00000000,B00001111,
104
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000111,
105
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000011,
106
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000001,
107
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000001,
108
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000001,
109
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000001,
110
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000001,
111
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000001,
112
+      B10001100,B00110000,B11000000,B00000000,B00000000,B00000000,B00000001,
113
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,
114
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
115
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111000
116
+    };
117
+
118
+    const unsigned char start_bmp3[] PROGMEM = {
119
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
120
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
121
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
122
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
123
+      B10000011,B11001111,B00000000,B00000000,B00000000,B00000000,B00111111,
124
+      B10000111,B11111111,B10000000,B00000000,B00000000,B00000000,B00011111,
125
+      B10000110,B01111001,B10000000,B00000000,B00000000,B00000000,B00001111,
126
+      B10001100,B00110000,B11000111,B10000000,B00000000,B00000000,B00000111,
127
+      B10001100,B00110000,B11001111,B11000000,B00000000,B00000000,B00000011,
128
+      B10001100,B00110000,B11011100,B11100000,B00000000,B00000000,B00000001,
129
+      B10001100,B00110000,B11011000,B01100000,B00000000,B00000000,B00000001,
130
+      B10001100,B00110000,B11010000,B01100000,B00000000,B00000000,B00000001,
131
+      B10001100,B00110000,B11011000,B01100000,B00000000,B00000000,B00000001,
132
+      B10001100,B00110000,B11011100,B01100000,B00000000,B00000000,B00000001,
133
+      B10001100,B00110000,B11001111,B01110000,B00000000,B00000000,B00000001,
134
+      B10001100,B00110000,B11000111,B01110000,B00000000,B00000000,B00000001,
135
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,
136
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
137
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111000
138
+    };
139
+
140
+    const unsigned char start_bmp4[] PROGMEM = {
141
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
142
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
143
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
144
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
145
+      B10000011,B11001111,B00000000,B00000000,B00000000,B00000000,B00111111,
146
+      B10000111,B11111111,B10000000,B00000000,B00000000,B00000000,B00011111,
147
+      B10000110,B01111001,B10000000,B00000000,B00000000,B00000000,B00001111,
148
+      B10001100,B00110000,B11000111,B10000011,B10000000,B00000000,B00000111,
149
+      B10001100,B00110000,B11001111,B11000111,B11000000,B00000000,B00000011,
150
+      B10001100,B00110000,B11011100,B11101100,B11100000,B00000000,B00000001,
151
+      B10001100,B00110000,B11011000,B01101100,B01100000,B00000000,B00000001,
152
+      B10001100,B00110000,B11010000,B01101100,B00000000,B00000000,B00000001,
153
+      B10001100,B00110000,B11011000,B01101100,B00000000,B00000000,B00000001,
154
+      B10001100,B00110000,B11011100,B01101100,B00000000,B00000000,B00000001,
155
+      B10001100,B00110000,B11001111,B01111100,B00000000,B00000000,B00000001,
156
+      B10001100,B00110000,B11000111,B01111100,B00000000,B00000000,B00000001,
157
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,
158
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
159
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111000
160
+    };
161
+
162
+    const unsigned char start_bmp5[] PROGMEM = {
163
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
164
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
165
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
166
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
167
+      B10000011,B11001111,B00000000,B00000000,B00001100,B00000000,B00111111,
168
+      B10000111,B11111111,B10000000,B00000000,B00001100,B00000000,B00011111,
169
+      B10000110,B01111001,B10000000,B00000000,B00001100,B00000000,B00001111,
170
+      B10001100,B00110000,B11000111,B10000011,B10001100,B00000000,B00000111,
171
+      B10001100,B00110000,B11001111,B11000111,B11001100,B00000000,B00000011,
172
+      B10001100,B00110000,B11011100,B11101100,B11101100,B00000000,B00000001,
173
+      B10001100,B00110000,B11011000,B01101100,B01101100,B00000000,B00000001,
174
+      B10001100,B00110000,B11010000,B01101100,B00001100,B00000000,B00000001,
175
+      B10001100,B00110000,B11011000,B01101100,B00001100,B00000000,B00000001,
176
+      B10001100,B00110000,B11011100,B01101100,B00001110,B00000000,B00000001,
177
+      B10001100,B00110000,B11001111,B01111100,B00000111,B10000000,B00000001,
178
+      B10001100,B00110000,B11000111,B01111100,B00000011,B10000000,B00000001,
179
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,
180
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
181
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111000
182
+    };
183
+
184
+    const unsigned char start_bmp6[] PROGMEM = {
185
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
186
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
187
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
188
+      B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
189
+      B10000011,B11001111,B00000000,B00000000,B00001100,B00110000,B00111111,
190
+      B10000111,B11111111,B10000000,B00000000,B00001100,B00110000,B00011111,
191
+      B10000110,B01111001,B10000000,B00000000,B00001100,B00000000,B00001111,
192
+      B10001100,B00110000,B11000111,B10000011,B10001100,B00110000,B00000111,
193
+      B10001100,B00110000,B11001111,B11000111,B11001100,B00110000,B00000011,
194
+      B10001100,B00110000,B11011100,B11101100,B11101100,B00110000,B00000001,
195
+      B10001100,B00110000,B11011000,B01101100,B01101100,B00110000,B00000001,
196
+      B10001100,B00110000,B11010000,B01101100,B00001100,B00110000,B00000001,
197
+      B10001100,B00110000,B11011000,B01101100,B00001100,B00110000,B00000001,
198
+      B10001100,B00110000,B11011100,B01101100,B00001110,B00111000,B00000001,
199
+      B10001100,B00110000,B11001111,B01111100,B00000111,B10011100,B00000001,
200
+      B10001100,B00110000,B11000111,B01111100,B00000011,B10001100,B00000001,
201
+      B01000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,
202
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
203
+      B00011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111000
204
+    };
205
+
206
+  #endif
207
+
72 208
 #else
73 209
 
74 210
   #define START_BMPWIDTH      112
@@ -114,10 +250,269 @@
114 250
     B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000
115 251
   };
116 252
 
253
+  #if ENABLED(BOOT_MARLIN_LOGO_ANIMATED)
254
+
255
+    const unsigned char start_bmp1[] PROGMEM = {
256
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
257
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
258
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,B11111111,
259
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,B11111111,
260
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,B11111111,
261
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111,
262
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,B11111111,
263
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,B11111111,
264
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,B11111111,
265
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,B11111111,
266
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,
267
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,
268
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
269
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
270
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
271
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,
272
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,
273
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,
274
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
275
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
276
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
277
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
278
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
279
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
280
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
281
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
282
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
283
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
284
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
285
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
286
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
287
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
288
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
289
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001110,
290
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011100,
291
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,
292
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
293
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000
294
+    };
295
+
296
+    const unsigned char start_bmp2[] PROGMEM = {
297
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
298
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
299
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,B11111111,
300
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,B11111111,
301
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,B11111111,
302
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111,
303
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,B11111111,
304
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,B11111111,
305
+      B11000000,B00001111,B11000000,B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,B11111111,
306
+      B11000000,B00111111,B11100001,B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,B11111111,
307
+      B11000000,B01111111,B11110011,B11111111,B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,
308
+      B11000000,B11111111,B11111111,B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,
309
+      B11000001,B11111000,B01111111,B10000111,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
310
+      B11000001,B11110000,B00111111,B00000011,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
311
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
312
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,
313
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,
314
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,
315
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
316
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
317
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
318
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
319
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
320
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
321
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
322
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
323
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
324
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
325
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
326
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
327
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
328
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
329
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
330
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001110,
331
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011100,
332
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,
333
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
334
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000
335
+    };
336
+
337
+    const unsigned char start_bmp3[] PROGMEM = {
338
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
339
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
340
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,B11111111,
341
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,B11111111,
342
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,B11111111,
343
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111,
344
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,B11111111,
345
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,B11111111,
346
+      B11000000,B00001111,B11000000,B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,B11111111,
347
+      B11000000,B00111111,B11100001,B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,B11111111,
348
+      B11000000,B01111111,B11110011,B11111111,B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,
349
+      B11000000,B11111111,B11111111,B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,
350
+      B11000001,B11111000,B01111111,B10000111,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
351
+      B11000001,B11110000,B00111111,B00000011,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
352
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00011111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,
353
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,
354
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,
355
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B11110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,
356
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11110011,B11111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
357
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11100000,B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
358
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B01111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
359
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B01111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
360
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
361
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
362
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
363
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B00111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
364
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11100000,B00111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
365
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B00111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
366
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B00111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
367
+      B11000001,B11100000,B00011110,B00000001,B11100000,B11111111,B00111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
368
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B00111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
369
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
370
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
371
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001110,
372
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011100,
373
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,
374
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
375
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000
376
+    };
377
+
378
+    const unsigned char start_bmp4[] PROGMEM = {
379
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
380
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
381
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,B11111111,
382
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,B11111111,
383
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,B11111111,
384
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111,
385
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,B11111111,
386
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,B11111111,
387
+      B11000000,B00001111,B11000000,B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,B11111111,
388
+      B11000000,B00111111,B11100001,B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001111,B11111111,
389
+      B11000000,B01111111,B11110011,B11111111,B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,
390
+      B11000000,B11111111,B11111111,B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,
391
+      B11000001,B11111000,B01111111,B10000111,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,
392
+      B11000001,B11110000,B00111111,B00000011,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,
393
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00011111,B00000000,B00000011,B11100000,B00000000,B00000000,B00000000,B00000000,B01111111,
394
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B11000000,B00001111,B11111000,B00000000,B00000000,B00000000,B00000000,B00111111,
395
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B11100000,B00011111,B11111100,B00000000,B00000000,B00000000,B00000000,B00011111,
396
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B11110000,B00111111,B11111110,B00000000,B00000000,B00000000,B00000000,B00001111,
397
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11110011,B11111000,B00111111,B00111110,B00000000,B00000000,B00000000,B00000000,B00000111,
398
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11100000,B11111100,B01111100,B00011111,B00000000,B00000000,B00000000,B00000000,B00000111,
399
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B01111100,B01111100,B00001111,B00000000,B00000000,B00000000,B00000000,B00000011,
400
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B01111100,B01111000,B00001111,B00000000,B00000000,B00000000,B00000000,B00000011,
401
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
402
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
403
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
404
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B00111100,B01111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
405
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11100000,B00111100,B01111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
406
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B00111111,B11111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
407
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B00111111,B11111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
408
+      B11000001,B11100000,B00011110,B00000001,B11100000,B11111111,B00111111,B11111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
409
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B00111111,B11111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,
410
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
411
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
412
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001110,
413
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011100,
414
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,
415
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
416
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000
417
+    };
418
+
419
+    const unsigned char start_bmp5[] PROGMEM = {
420
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
421
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
422
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,B11111111,
423
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,B11111111,
424
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,B11111111,
425
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111,
426
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,B11111111,
427
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00111111,B11111111,
428
+      B11000000,B00001111,B11000000,B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00011111,B11111111,
429
+      B11000000,B00111111,B11100001,B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00001111,B11111111,
430
+      B11000000,B01111111,B11110011,B11111111,B10000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000111,B11111111,
431
+      B11000000,B11111111,B11111111,B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000011,B11111111,
432
+      B11000001,B11111000,B01111111,B10000111,B11100000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000001,B11111111,
433
+      B11000001,B11110000,B00111111,B00000011,B11100000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000000,B11111111,
434
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00011111,B00000000,B00000011,B11100000,B01111000,B00000000,B00000000,B00000000,B01111111,
435
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B11000000,B00001111,B11111000,B01111000,B00000000,B00000000,B00000000,B00111111,
436
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B11100000,B00011111,B11111100,B01111000,B00000000,B00000000,B00000000,B00011111,
437
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B11110000,B00111111,B11111110,B01111000,B00000000,B00000000,B00000000,B00001111,
438
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11110011,B11111000,B00111111,B00111110,B01111000,B00000000,B00000000,B00000000,B00000111,
439
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11100000,B11111100,B01111100,B00011111,B01111000,B00000000,B00000000,B00000000,B00000111,
440
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B01111100,B01111100,B00001111,B01111000,B00000000,B00000000,B00000000,B00000011,
441
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B01111100,B01111000,B00001111,B01111000,B00000000,B00000000,B00000000,B00000011,
442
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00000000,B00000000,B00000000,B00000011,
443
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00000000,B00000000,B00000000,B00000011,
444
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00000000,B00000000,B00000000,B00000011,
445
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B00111100,B01111000,B00000000,B01111000,B00000000,B00000000,B00000000,B00000011,
446
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11100000,B00111100,B01111000,B00000000,B01111100,B00000000,B00000000,B00000000,B00000011,
447
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B00111111,B11111000,B00000000,B01111111,B00000000,B00000000,B00000000,B00000011,
448
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B00111111,B11111000,B00000000,B00111111,B00000000,B00000000,B00000000,B00000011,
449
+      B11000001,B11100000,B00011110,B00000001,B11100000,B11111111,B00111111,B11111000,B00000000,B00011111,B00000000,B00000000,B00000000,B00000011,
450
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B00111111,B11111000,B00000000,B00001111,B00000000,B00000000,B00000000,B00000011,
451
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
452
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
453
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001110,
454
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011100,
455
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,
456
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
457
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000
458
+    };
459
+
460
+    const unsigned char start_bmp6[] PROGMEM = {
461
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
462
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
463
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111111,B11111111,
464
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111111,B11111111,
465
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111111,B11111111,
466
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111,
467
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111111,B11111111,
468
+      B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00111111,B11111111,
469
+      B11000000,B00001111,B11000000,B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00011000,B00000000,B00011111,B11111111,
470
+      B11000000,B00111111,B11100001,B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B00000000,B00001111,B11111111,
471
+      B11000000,B01111111,B11110011,B11111111,B10000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B00000000,B00000111,B11111111,
472
+      B11000000,B11111111,B11111111,B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B00000000,B00000011,B11111111,
473
+      B11000001,B11111000,B01111111,B10000111,B11100000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000001,B11111111,
474
+      B11000001,B11110000,B00111111,B00000011,B11100000,B00000000,B00000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000000,B11111111,
475
+      B11000001,B11100000,B00011110,B00000001,B11100000,B00011111,B00000000,B00000011,B11100000,B01111000,B00111100,B00000000,B00000000,B01111111,
476
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B11000000,B00001111,B11111000,B01111000,B00111100,B00000000,B00000000,B00111111,
477
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B11100000,B00011111,B11111100,B01111000,B00111100,B00000000,B00000000,B00011111,
478
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B11110000,B00111111,B11111110,B01111000,B00111100,B00000000,B00000000,B00001111,
479
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11110011,B11111000,B00111111,B00111110,B01111000,B00111100,B00000000,B00000000,B00000111,
480
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11100000,B11111100,B01111100,B00011111,B01111000,B00111100,B00000000,B00000000,B00000111,
481
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B01111100,B01111100,B00001111,B01111000,B00111100,B00000000,B00000000,B00000011,
482
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B01111100,B01111000,B00001111,B01111000,B00111100,B00000000,B00000000,B00000011,
483
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00000000,B00000000,B00000011,
484
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00000000,B00000000,B00000011,
485
+      B11000001,B11100000,B00011110,B00000001,B11100111,B10000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00000000,B00000000,B00000011,
486
+      B11000001,B11100000,B00011110,B00000001,B11100111,B11000000,B00111100,B01111000,B00000000,B01111000,B00111100,B00000000,B00000000,B00000011,
487
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11100000,B00111100,B01111000,B00000000,B01111100,B00111100,B00000000,B00000000,B00000011,
488
+      B11000001,B11100000,B00011110,B00000001,B11100011,B11111111,B00111111,B11111000,B00000000,B01111111,B10111100,B00000000,B00000000,B00000011,
489
+      B11000001,B11100000,B00011110,B00000001,B11100001,B11111111,B00111111,B11111000,B00000000,B00111111,B10111111,B00000000,B00000000,B00000011,
490
+      B11000001,B11100000,B00011110,B00000001,B11100000,B11111111,B00111111,B11111000,B00000000,B00011111,B10111111,B00000000,B00000000,B00000011,
491
+      B11000001,B11100000,B00011110,B00000001,B11100000,B01111111,B00111111,B11111000,B00000000,B00001111,B10111111,B00000000,B00000000,B00000011,
492
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,
493
+      B01100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000110,
494
+      B01110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001110,
495
+      B00111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011100,
496
+      B00011110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01111000,
497
+      B00001111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
498
+      B00000001,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000000
499
+    };
500
+
501
+  #endif
502
+
503
+#endif
504
+
505
+#if ENABLED(BOOT_MARLIN_LOGO_ANIMATED)
506
+  #ifndef MARLIN_BOOTSCREEN_FRAME_TIME
507
+    #define MARLIN_BOOTSCREEN_FRAME_TIME 100 // (ms)
508
+  #endif
509
+  const unsigned char * const marlin_bootscreen_animation[] PROGMEM = {
510
+    start_bmp1, start_bmp2, start_bmp3, start_bmp4, start_bmp5, start_bmp6, start_bmp
511
+  };
117 512
 #endif
118 513
 
119 514
 #ifndef START_BMP_BYTEWIDTH
120
-  #define START_BMP_BYTEWIDTH ((START_BMPWIDTH + 7) / 8)
515
+  #define START_BMP_BYTEWIDTH CEILING(START_BMPWIDTH, 8)
121 516
 #endif
122 517
 #ifndef START_BMPHEIGHT
123 518
   #define START_BMPHEIGHT (sizeof(start_bmp) / (START_BMP_BYTEWIDTH))

+ 6
- 6
Marlin/src/lcd/dogm/dogm_Statusscreen.h View File

@@ -1220,10 +1220,10 @@
1220 1220
     #define STATUS_HOTEND4_WIDTH STATUS_HOTEND3_WIDTH
1221 1221
   #endif
1222 1222
   #ifndef STATUS_HOTEND5_WIDTH
1223
-    #define STATUS_HOTEND5_WIDTH STATUS_HOTEND5_WIDTH
1223
+    #define STATUS_HOTEND5_WIDTH STATUS_HOTEND4_WIDTH
1224 1224
   #endif
1225 1225
   #ifndef STATUS_HOTEND6_WIDTH
1226
-    #define STATUS_HOTEND6_WIDTH STATUS_HOTEND6_WIDTH
1226
+    #define STATUS_HOTEND6_WIDTH STATUS_HOTEND5_WIDTH
1227 1227
   #endif
1228 1228
 
1229 1229
   constexpr uint8_t status_hotend_width[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_WIDTH, STATUS_HOTEND2_WIDTH, STATUS_HOTEND3_WIDTH, STATUS_HOTEND4_WIDTH, STATUS_HOTEND5_WIDTH, STATUS_HOTEND6_WIDTH);
@@ -1264,10 +1264,10 @@
1264 1264
     #define STATUS_HOTEND4_X STATUS_HOTEND3_X + STATUS_HEATERS_XSPACE
1265 1265
   #endif
1266 1266
   #ifndef STATUS_HOTEND5_X
1267
-    #define STATUS_HOTEND5_X STATUS_HOTEND5_X + STATUS_HEATERS_XSPACE
1267
+    #define STATUS_HOTEND5_X STATUS_HOTEND4_X + STATUS_HEATERS_XSPACE
1268 1268
   #endif
1269 1269
   #ifndef STATUS_HOTEND6_X
1270
-    #define STATUS_HOTEND6_X STATUS_HOTEND6_X + STATUS_HEATERS_XSPACE
1270
+    #define STATUS_HOTEND6_X STATUS_HOTEND5_X + STATUS_HEATERS_XSPACE
1271 1271
   #endif
1272 1272
 
1273 1273
   #if HOTENDS > 2
@@ -1291,10 +1291,10 @@
1291 1291
         #define STATUS_HOTEND4_TEXT_X STATUS_HOTEND3_TEXT_X + STATUS_HEATERS_XSPACE
1292 1292
       #endif
1293 1293
       #ifndef STATUS_HOTEND5_TEXT_X
1294
-        #define STATUS_HOTEND5_TEXT_X STATUS_HOTEND5_TEXT_X + STATUS_HEATERS_XSPACE
1294
+        #define STATUS_HOTEND5_TEXT_X STATUS_HOTEND4_TEXT_X + STATUS_HEATERS_XSPACE
1295 1295
       #endif
1296 1296
       #ifndef STATUS_HOTEND6_TEXT_X
1297
-        #define STATUS_HOTEND6_TEXT_X STATUS_HOTEND6_TEXT_X + STATUS_HEATERS_XSPACE
1297
+        #define STATUS_HOTEND6_TEXT_X STATUS_HOTEND5_TEXT_X + STATUS_HEATERS_XSPACE
1298 1298
       #endif
1299 1299
       constexpr uint8_t status_hotend_text_x[] = ARRAY_N(HOTENDS, STATUS_HOTEND1_TEXT_X, STATUS_HOTEND2_TEXT_X, STATUS_HOTEND3_TEXT_X, STATUS_HOTEND4_TEXT_X, STATUS_HOTEND5_TEXT_X, STATUS_HOTEND6_TEXT_X);
1300 1300
       #define STATUS_HOTEND_TEXT_X(N) status_hotend_text_x[N]

+ 7
- 11
Marlin/src/lcd/dogm/lcdprint_u8g.cpp View File

@@ -22,7 +22,7 @@
22 22
 
23 23
 int lcd_glyph_height(void) { return u8g_GetFontBBXHeight(u8g.getU8g()); }
24 24
 
25
-void lcd_moveto(const uint8_t col, const uint8_t row) { u8g.setPrintPos(col, row); }
25
+void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) { u8g.setPrintPos(col, row); }
26 26
 
27 27
 void lcd_put_int(const int i) { u8g.print(i); }
28 28
 
@@ -33,26 +33,22 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
33 33
     u8g.print((char)c);
34 34
     return u8g_GetFontBBXWidth(u8g.getU8g());
35 35
   }
36
-  unsigned int x = u8g.getPrintCol(),
37
-               y = u8g.getPrintRow(),
38
-               ret = uxg_DrawWchar(u8g.getU8g(), x, y, c, max_length);
36
+  u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
37
+           ret = uxg_DrawWchar(u8g.getU8g(), x, y, c, max_length);
39 38
   u8g.setPrintPos(x + ret, y);
40
-
41 39
   return ret;
42 40
 }
43 41
 
44 42
 int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
45
-  unsigned int x = u8g.getPrintCol(),
46
-               y = u8g.getPrintRow(),
47
-               ret = uxg_DrawUtf8Str(u8g.getU8g(), x, y, utf8_str, max_length);
43
+  u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
44
+           ret = uxg_DrawUtf8Str(u8g.getU8g(), x, y, utf8_str, max_length);
48 45
   u8g.setPrintPos(x + ret, y);
49 46
   return ret;
50 47
 }
51 48
 
52 49
 int lcd_put_u8str_max_P(PGM_P utf8_str_P, pixel_len_t max_length) {
53
-  unsigned int x = u8g.getPrintCol(),
54
-               y = u8g.getPrintRow(),
55
-               ret = uxg_DrawUtf8StrP(u8g.getU8g(), x, y, utf8_str_P, max_length);
50
+  u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
51
+           ret = uxg_DrawUtf8StrP(u8g.getU8g(), x, y, utf8_str_P, max_length);
56 52
   u8g.setPrintPos(x + ret, y);
57 53
   return ret;
58 54
 }

+ 12
- 29
Marlin/src/lcd/dogm/status_screen_DOGM.cpp View File

@@ -100,8 +100,7 @@
100 100
 FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, const uint8_t ty) {
101 101
   const char *str = i16tostr3(temp);
102 102
   const uint8_t len = str[0] != ' ' ? 3 : str[1] != ' ' ? 2 : 1;
103
-  lcd_moveto(tx - len * (INFO_FONT_WIDTH) / 2 + 1, ty);
104
-  lcd_put_u8str(&str[3-len]);
103
+  lcd_put_u8str(tx - len * (INFO_FONT_WIDTH) / 2 + 1, ty, &str[3-len]);
105 104
   lcd_put_wchar(LCD_STR_DEGREE[0]);
106 105
 }
107 106
 
@@ -264,8 +263,7 @@ FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const bool blin
264 263
 //
265 264
 FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const bool blink) {
266 265
   const uint8_t offs = (XYZ_SPACING) * axis;
267
-  lcd_moveto(X_LABEL_POS + offs, XYZ_BASELINE);
268
-  lcd_put_wchar('X' + axis);
266
+  lcd_put_wchar(X_LABEL_POS + offs, XYZ_BASELINE, 'X' + axis);
269 267
   lcd_moveto(X_VALUE_POS + offs, XYZ_BASELINE);
270 268
   if (blink)
271 269
     lcd_put_u8str(value);
@@ -429,8 +427,7 @@ void MarlinUI::draw_status_screen() {
429 427
               c = '*';
430 428
             }
431 429
           #endif
432
-          lcd_moveto(STATUS_FAN_TEXT_X, STATUS_FAN_TEXT_Y);
433
-          lcd_put_u8str(i16tostr3(thermalManager.fanPercent(spd)));
430
+          lcd_put_u8str(STATUS_FAN_TEXT_X, STATUS_FAN_TEXT_Y, i16tostr3(thermalManager.fanPercent(spd)));
434 431
           lcd_put_wchar(c);
435 432
         }
436 433
       }
@@ -488,8 +485,7 @@ void MarlinUI::draw_status_screen() {
488 485
       #if ENABLED(DOGM_SD_PERCENT)
489 486
         if (PAGE_CONTAINS(41, 48)) {
490 487
           // Percent complete
491
-          lcd_moveto(55, 48);
492
-          lcd_put_u8str(ui8tostr3(progress));
488
+          lcd_put_u8str(55, 48, ui8tostr3(progress));
493 489
           lcd_put_wchar('%');
494 490
         }
495 491
       #endif
@@ -510,8 +506,7 @@ void MarlinUI::draw_status_screen() {
510 506
       duration_t elapsed = print_job_timer.duration();
511 507
       bool has_days = (elapsed.value >= 60*60*24L);
512 508
       uint8_t len = elapsed.toDigital(buffer, has_days);
513
-      lcd_moveto(SD_DURATION_X, EXTRAS_BASELINE);
514
-      lcd_put_u8str(buffer);
509
+      lcd_put_u8str(SD_DURATION_X, EXTRAS_BASELINE, buffer);
515 510
     }
516 511
 
517 512
   #endif // HAS_PRINT_PROGRESS
@@ -520,10 +515,6 @@ void MarlinUI::draw_status_screen() {
520 515
   // XYZ Coordinates
521 516
   //
522 517
 
523
-  #define X_LABEL_POS  3
524
-  #define X_VALUE_POS 11
525
-  #define XYZ_SPACING 37
526
-
527 518
   #if ENABLED(XYZ_HOLLOW_FRAME)
528 519
     #define XYZ_FRAME_TOP 29
529 520
     #define XYZ_FRAME_HEIGHT INFO_FONT_ASCENT + 3
@@ -550,8 +541,6 @@ void MarlinUI::draw_status_screen() {
550 541
 
551 542
         // Two-component mix / gradient instead of XY
552 543
 
553
-        lcd_moveto(X_LABEL_POS, XYZ_BASELINE);
554
-
555 544
         char mixer_messages[12];
556 545
         const char *mix_label;
557 546
         #if ENABLED(GRADIENT_MIX)
@@ -566,7 +555,7 @@ void MarlinUI::draw_status_screen() {
566 555
             mix_label = "Mx";
567 556
           }
568 557
         sprintf_P(mixer_messages, PSTR("%s %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1]));
569
-        lcd_put_u8str(mixer_messages);
558
+        lcd_put_u8str(X_LABEL_POS, XYZ_BASELINE, mixer_messages);
570 559
 
571 560
       #else
572 561
 
@@ -591,28 +580,22 @@ void MarlinUI::draw_status_screen() {
591 580
 
592 581
   if (PAGE_CONTAINS(EXTRAS_2_BASELINE - INFO_FONT_ASCENT, EXTRAS_2_BASELINE - 1)) {
593 582
     set_font(FONT_MENU);
594
-    lcd_moveto(3, EXTRAS_2_BASELINE);
595
-    lcd_put_wchar(LCD_STR_FEEDRATE[0]);
583
+    lcd_put_wchar(3, EXTRAS_2_BASELINE, LCD_STR_FEEDRATE[0]);
596 584
 
597 585
     set_font(FONT_STATUSMENU);
598
-    lcd_moveto(12, EXTRAS_2_BASELINE);
599
-    lcd_put_u8str(i16tostr3(feedrate_percentage));
586
+    lcd_put_u8str(12, EXTRAS_2_BASELINE, i16tostr3(feedrate_percentage));
600 587
     lcd_put_wchar('%');
601 588
 
602 589
     //
603 590
     // Filament sensor display if SD is disabled
604 591
     //
605 592
     #if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT)
606
-      lcd_moveto(56, EXTRAS_2_BASELINE);
607
-      lcd_put_u8str(wstring);
608
-      lcd_moveto(102, EXTRAS_2_BASELINE);
609
-      lcd_put_u8str(mstring);
593
+      lcd_put_u8str(56, EXTRAS_2_BASELINE, wstring);
594
+      lcd_put_u8str(102, EXTRAS_2_BASELINE, mstring);
610 595
       lcd_put_wchar('%');
611 596
       set_font(FONT_MENU);
612
-      lcd_moveto(47, EXTRAS_2_BASELINE);
613
-      lcd_put_wchar(LCD_STR_FILAM_DIA[0]); // lcd_put_u8str_P(PSTR(LCD_STR_FILAM_DIA));
614
-      lcd_moveto(93, EXTRAS_2_BASELINE);
615
-      lcd_put_wchar(LCD_STR_FILAM_MUL[0]);
597
+      lcd_put_wchar(47, EXTRAS_2_BASELINE, LCD_STR_FILAM_DIA[0]); // lcd_put_u8str_P(PSTR(LCD_STR_FILAM_DIA));
598
+      lcd_put_wchar(93, EXTRAS_2_BASELINE, LCD_STR_FILAM_MUL[0]);
616 599
     #endif
617 600
   }
618 601
 

+ 74
- 74
Marlin/src/lcd/dogm/ultralcd_DOGM.cpp View File

@@ -102,30 +102,29 @@ void MarlinUI::set_font(const MarlinFont font_nr) {
102 102
   }
103 103
 }
104 104
 
105
+bool MarlinUI::detected() { return true; }
106
+
105 107
 #if ENABLED(SHOW_BOOTSCREEN)
106 108
 
107 109
   #if ENABLED(SHOW_CUSTOM_BOOTSCREEN)
108 110
     // Draws a slice of a particular frame of the custom bootscreen, without the u8g loop
109 111
     void MarlinUI::draw_custom_bootscreen(const uint8_t frame/*=0*/) {
110 112
       constexpr u8g_uint_t left = u8g_uint_t((LCD_PIXEL_WIDTH  - (CUSTOM_BOOTSCREEN_BMPWIDTH)) / 2),
111
-                           top = u8g_uint_t((LCD_PIXEL_HEIGHT - (CUSTOM_BOOTSCREEN_BMPHEIGHT)) / 2);
113
+                            top = u8g_uint_t((LCD_PIXEL_HEIGHT - (CUSTOM_BOOTSCREEN_BMPHEIGHT)) / 2);
112 114
       #if ENABLED(CUSTOM_BOOTSCREEN_INVERTED)
113 115
         constexpr u8g_uint_t right = left + CUSTOM_BOOTSCREEN_BMPWIDTH,
114 116
                             bottom = top + CUSTOM_BOOTSCREEN_BMPHEIGHT;
115 117
       #endif
116 118
 
117 119
       const u8g_pgm_uint8_t * const bmp =
118
-        #if ENABLED(ANIMATED_BOOTSCREEN)
120
+        #if ENABLED(CUSTOM_BOOTSCREEN_ANIMATED)
119 121
           (u8g_pgm_uint8_t*)pgm_read_ptr(&custom_bootscreen_animation[frame])
120 122
         #else
121 123
           custom_start_bmp
122 124
         #endif
123 125
       ;
124 126
 
125
-      u8g.drawBitmapP(
126
-        left, top,
127
-        CEILING(CUSTOM_BOOTSCREEN_BMPWIDTH, 8), CUSTOM_BOOTSCREEN_BMPHEIGHT, bmp
128
-      );
127
+      u8g.drawBitmapP(left, top, CUSTOM_BOOTSCREEN_BMP_BYTEWIDTH, CUSTOM_BOOTSCREEN_BMPHEIGHT, bmp);
129 128
 
130 129
       #if ENABLED(CUSTOM_BOOTSCREEN_INVERTED)
131 130
         if (frame == 0) {
@@ -140,7 +139,7 @@ void MarlinUI::set_font(const MarlinFont font_nr) {
140 139
 
141 140
     // Shows the custom bootscreen, with the u8g loop, animations and delays
142 141
     void MarlinUI::show_custom_bootscreen() {
143
-      #if DISABLED(ANIMATED_BOOTSCREEN)
142
+      #if DISABLED(CUSTOM_BOOTSCREEN_ANIMATED)
144 143
         constexpr millis_t d = 0;
145 144
         constexpr uint8_t f = 0;
146 145
       #else
@@ -163,23 +162,22 @@ void MarlinUI::set_font(const MarlinFont font_nr) {
163 162
   // Draws a slice of the Marlin bootscreen, without the u8g loop
164 163
   void MarlinUI::draw_marlin_bootscreen() {
165 164
     // Screen dimensions.
166
-    //const uint8_t width = u8g.getWidth(), height = u8g.getHeight();
167
-    constexpr uint8_t width = LCD_PIXEL_WIDTH, height = LCD_PIXEL_HEIGHT;
165
+    //const u8g_uint_t width = u8g.getWidth(), height = u8g.getHeight();
166
+    constexpr u8g_uint_t width = LCD_PIXEL_WIDTH, height = LCD_PIXEL_HEIGHT;
168 167
 
169 168
     // Determine text space needed
170 169
     #ifndef STRING_SPLASH_LINE2
171
-      constexpr uint8_t text_total_height = MENU_FONT_HEIGHT,
172
-                        text_width_1 = uint8_t(sizeof(STRING_SPLASH_LINE1) - 1) * uint8_t(MENU_FONT_WIDTH),
173
-                        text_width_2 = 0;
170
+      constexpr u8g_uint_t text_total_height = MENU_FONT_HEIGHT,
171
+                           text_width_2 = 0;
174 172
     #else
175
-      constexpr uint8_t text_total_height = uint8_t(MENU_FONT_HEIGHT) * 2,
176
-                        text_width_1 = uint8_t(sizeof(STRING_SPLASH_LINE1) - 1) * uint8_t(MENU_FONT_WIDTH),
177
-                        text_width_2 = uint8_t(sizeof(STRING_SPLASH_LINE2) - 1) * uint8_t(MENU_FONT_WIDTH);
173
+      constexpr u8g_uint_t text_total_height = (MENU_FONT_HEIGHT) * 2,
174
+                           text_width_2 = u8g_uint_t((sizeof(STRING_SPLASH_LINE2) - 1) * (MENU_FONT_WIDTH));
178 175
     #endif
179
-    constexpr uint8_t text_max_width = _MAX(text_width_1, text_width_2),
180
-                      rspace = width - (START_BMPWIDTH);
176
+    constexpr u8g_uint_t text_width_1 = u8g_uint_t((sizeof(STRING_SPLASH_LINE1) - 1) * (MENU_FONT_WIDTH)),
177
+                         text_max_width = _MAX(text_width_1, text_width_2),
178
+                         rspace = width - (START_BMPWIDTH);
181 179
 
182
-    int8_t offx, offy, txt_base, txt_offx_1, txt_offx_2;
180
+    u8g_int_t offx, offy, txt_base, txt_offx_1, txt_offx_2;
183 181
 
184 182
     // Can the text fit to the right of the bitmap?
185 183
     if (text_max_width < rspace) {
@@ -200,13 +198,29 @@ void MarlinUI::set_font(const MarlinFont font_nr) {
200 198
     NOLESS(offx, 0);
201 199
     NOLESS(offy, 0);
202 200
 
203
-    u8g.drawBitmapP(offx, offy, (START_BMPWIDTH + 7) / 8, START_BMPHEIGHT, start_bmp);
204
-    set_font(FONT_MENU);
205
-    #ifndef STRING_SPLASH_LINE2
206
-      u8g.drawStr(txt_offx_1, txt_base, STRING_SPLASH_LINE1);
201
+    auto draw_bootscreen_bmp = [&](const uint8_t *bitmap) {
202
+      u8g.drawBitmapP(offx, offy, START_BMP_BYTEWIDTH, START_BMPHEIGHT, bitmap);
203
+      set_font(FONT_MENU);
204
+      #ifndef STRING_SPLASH_LINE2
205
+        lcd_put_u8str_P(txt_offx_1, txt_base, PSTR(STRING_SPLASH_LINE1));
206
+      #else
207
+        lcd_put_u8str_P(txt_offx_1, txt_base - (MENU_FONT_HEIGHT), PSTR(STRING_SPLASH_LINE1));
208
+        lcd_put_u8str_P(txt_offx_2, txt_base, PSTR(STRING_SPLASH_LINE2));
209
+      #endif
210
+    };
211
+
212
+    #if DISABLED(BOOT_MARLIN_LOGO_ANIMATED)
213
+      draw_bootscreen_bmp(start_bmp);
207 214
     #else
208
-      u8g.drawStr(txt_offx_1, txt_base - (MENU_FONT_HEIGHT), STRING_SPLASH_LINE1);
209
-      u8g.drawStr(txt_offx_2, txt_base, STRING_SPLASH_LINE2);
215
+      constexpr millis_t d = MARLIN_BOOTSCREEN_FRAME_TIME;
216
+      LOOP_L_N(f, COUNT(marlin_bootscreen_animation)) {
217
+        u8g.firstPage();
218
+        do {
219
+          const u8g_pgm_uint8_t * const bmp = (u8g_pgm_uint8_t*)pgm_read_ptr(&marlin_bootscreen_animation[f]);
220
+          draw_bootscreen_bmp(bmp);
221
+        } while (u8g.nextPage());
222
+        if (d) safe_delay(d);
223
+      }
210 224
     #endif
211 225
   }
212 226
 
@@ -286,16 +300,13 @@ void MarlinUI::draw_kill_screen() {
286 300
   #if ENABLED(LIGHTWEIGHT_UI)
287 301
     ST7920_Lite_Status_Screen::clear_text_buffer();
288 302
   #endif
289
-  const uint8_t h4 = u8g.getHeight() / 4;
303
+  const u8g_uint_t h4 = u8g.getHeight() / 4;
290 304
   u8g.firstPage();
291 305
   do {
292 306
     set_font(FONT_MENU);
293
-    lcd_moveto(0, h4 * 1);
294
-    lcd_put_u8str(status_message);
295
-    lcd_moveto(0, h4 * 2);
296
-    lcd_put_u8str_P(PSTR(MSG_HALTED));
297
-    lcd_moveto(0, h4 * 3);
298
-    lcd_put_u8str_P(PSTR(MSG_PLEASE_RESET));
307
+    lcd_put_u8str(0, h4 * 1, status_message);
308
+    lcd_put_u8str_P(0, h4 * 2, PSTR(MSG_HALTED));
309
+    lcd_put_u8str_P(0, h4 * 3, PSTR(MSG_PLEASE_RESET));
299 310
   } while (u8g.nextPage());
300 311
 }
301 312
 
@@ -303,7 +314,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
303 314
 
304 315
 #if HAS_LCD_MENU
305 316
 
306
-  uint8_t row_y1, row_y2;
317
+  u8g_uint_t row_y1, row_y2;
307 318
 
308 319
   #if ENABLED(ADVANCED_PAUSE_FEATURE)
309 320
 
@@ -313,8 +324,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
313 324
 
314 325
       if (!PAGE_CONTAINS(row_y1 + 1, row_y2 + 2)) return;
315 326
 
316
-      lcd_moveto(LCD_PIXEL_WIDTH - 11 * (MENU_FONT_WIDTH), row_y2);
317
-      lcd_put_wchar('E');
327
+      lcd_put_wchar(LCD_PIXEL_WIDTH - 11 * (MENU_FONT_WIDTH), row_y2, 'E');
318 328
       lcd_put_wchar((char)('1' + extruder));
319 329
       lcd_put_wchar(' ');
320 330
       lcd_put_u8str(i16tostr3(thermalManager.degHotend(extruder)));
@@ -360,7 +370,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
360 370
 
361 371
     if (mark_as_selected(row, invert)) {
362 372
 
363
-      uint8_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed
373
+      u8g_uint_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed
364 374
 
365 375
       if (center && !valstr) {
366 376
         int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
@@ -377,11 +387,10 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
377 387
     UNUSED(pre_char);
378 388
 
379 389
     if (mark_as_selected(row, sel)) {
380
-      uint8_t n = (LCD_WIDTH - 2) * (MENU_FONT_WIDTH);
390
+      u8g_uint_t n = (LCD_WIDTH - 2) * (MENU_FONT_WIDTH);
381 391
       n -= lcd_put_u8str_max_P(pstr, n);
382 392
       while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
383
-      lcd_moveto(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2);
384
-      lcd_put_wchar(post_char);
393
+      lcd_put_wchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char);
385 394
       lcd_put_wchar(' ');
386 395
     }
387 396
   }
@@ -390,7 +399,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
390 399
   void _draw_menu_item_edit(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
391 400
     if (mark_as_selected(row, sel)) {
392 401
       const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
393
-      uint8_t n = (LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH);
402
+      u8g_uint_t n = (LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH);
394 403
       n -= lcd_put_u8str_max_P(pstr, n);
395 404
       lcd_put_wchar(':');
396 405
       while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
@@ -402,13 +411,13 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
402 411
   void draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
403 412
     ui.encoder_direction_normal();
404 413
 
405
-    const uint8_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value);
414
+    const u8g_uint_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value);
406 415
     bool extra_row = labellen > LCD_WIDTH - 2 - vallen;
407 416
 
408 417
     #if ENABLED(USE_BIG_EDIT_FONT)
409 418
       // Use the menu font if the label won't fit on a single line
410
-      constexpr uint8_t lcd_edit_width = (LCD_PIXEL_WIDTH) / (EDIT_FONT_WIDTH);
411
-      uint8_t lcd_chr_fit, one_chr_width;
419
+      constexpr u8g_uint_t lcd_edit_width = (LCD_PIXEL_WIDTH) / (EDIT_FONT_WIDTH);
420
+      u8g_uint_t lcd_chr_fit, one_chr_width;
412 421
       if (labellen <= lcd_edit_width - 1) {
413 422
         if (labellen + vallen + 1 > lcd_edit_width) extra_row = true;
414 423
         lcd_chr_fit = lcd_edit_width + 1;
@@ -421,20 +430,17 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
421 430
         ui.set_font(FONT_MENU);
422 431
       }
423 432
     #else
424
-      constexpr uint8_t lcd_chr_fit = LCD_WIDTH,
425
-                        one_chr_width = MENU_FONT_WIDTH;
433
+      constexpr u8g_uint_t lcd_chr_fit = LCD_WIDTH,
434
+                           one_chr_width = MENU_FONT_WIDTH;
426 435
     #endif
427 436
 
428 437
     // Center the label and value lines on the middle line
429
-    uint8_t baseline = extra_row ? (LCD_PIXEL_HEIGHT) / 2 - 1
430
-                                 : (LCD_PIXEL_HEIGHT + EDIT_FONT_ASCENT) / 2;
438
+    u8g_uint_t baseline = extra_row ? (LCD_PIXEL_HEIGHT) / 2 - 1
439
+                                    : (LCD_PIXEL_HEIGHT + EDIT_FONT_ASCENT) / 2;
431 440
 
432 441
     // Assume the label is alpha-numeric (with a descender)
433 442
     bool onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline + EDIT_FONT_DESCENT);
434
-    if (onpage) {
435
-      lcd_moveto(0, baseline);
436
-      lcd_put_u8str_P(pstr);
437
-    }
443
+    if (onpage) lcd_put_u8str_P(0, baseline, pstr);
438 444
 
439 445
     // If a value is included, print a colon, then print the value right-justified
440 446
     if (value != nullptr) {
@@ -445,23 +451,21 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
445 451
         onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline);
446 452
       }
447 453
       if (onpage) {
448
-        lcd_moveto(((lcd_chr_fit - 1) - (vallen + 1)) * one_chr_width, baseline); // Right-justified, leaving padded by spaces
449
-        lcd_put_wchar(' '); // overwrite char if value gets shorter
454
+        lcd_put_wchar(((lcd_chr_fit - 1) - (vallen + 1)) * one_chr_width, baseline, ' '); // Right-justified, padded, add a leading space
450 455
         lcd_put_u8str(value);
451 456
       }
452 457
     }
453 458
   }
454 459
 
455
-  inline void draw_boxed_string(const uint8_t x, const uint8_t y, PGM_P const pstr, const bool inv) {
456
-    const uint8_t len = utf8_strlen_P(pstr), bw = len * (MENU_FONT_WIDTH),
457
-                  bx = x * (MENU_FONT_WIDTH), by = (y + 1) * (MENU_FONT_HEIGHT);
460
+  inline void draw_boxed_string(const u8g_uint_t x, const u8g_uint_t y, PGM_P const pstr, const bool inv) {
461
+    const u8g_uint_t len = utf8_strlen_P(pstr), bw = len * (MENU_FONT_WIDTH),
462
+                     bx = x * (MENU_FONT_WIDTH), by = (y + 1) * (MENU_FONT_HEIGHT);
458 463
     if (inv) {
459 464
       u8g.setColorIndex(1);
460 465
       u8g.drawBox(bx - 1, by - (MENU_FONT_ASCENT) + 1, bw + 2, MENU_FONT_HEIGHT - 1);
461 466
       u8g.setColorIndex(0);
462 467
     }
463
-    lcd_moveto(bx, by);
464
-    lcd_put_u8str_P(pstr);
468
+    lcd_put_u8str_P(bx, by, pstr);
465 469
     if (inv) u8g.setColorIndex(1);
466 470
   }
467 471
 
@@ -479,8 +483,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
479 483
       if (mark_as_selected(row, sel)) {
480 484
         if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]);
481 485
         constexpr uint8_t maxlen = LCD_WIDTH - 1;
482
-        const uint8_t pixw = maxlen * (MENU_FONT_WIDTH);
483
-        uint8_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
486
+        const u8g_uint_t pixw = maxlen * (MENU_FONT_WIDTH);
487
+        u8g_uint_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
484 488
         while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
485 489
       }
486 490
     }
@@ -499,8 +503,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
499 503
 
500 504
     void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) {
501 505
       // Scale the box pixels appropriately
502
-      uint8_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X),
503
-              y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y),
506
+      u8g_uint_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X),
507
+                 y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y),
504 508
 
505 509
               pixels_per_x_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X),
506 510
               pixels_per_y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y),
@@ -522,8 +526,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
522 526
       // Display Mesh Point Locations
523 527
 
524 528
       u8g.setColorIndex(1);
525
-      const uint8_t sx = x_offset + pixels_per_x_mesh_pnt / 2;
526
-            uint8_t  y = y_offset + pixels_per_y_mesh_pnt / 2;
529
+      const u8g_uint_t sx = x_offset + pixels_per_x_mesh_pnt / 2;
530
+            u8g_uint_t  y = y_offset + pixels_per_y_mesh_pnt / 2;
527 531
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++, y += pixels_per_y_mesh_pnt)
528 532
         if (PAGE_CONTAINS(y, y))
529 533
           for (uint8_t i = 0, x = sx; i < GRID_MAX_POINTS_X; i++, x += pixels_per_x_mesh_pnt)
@@ -531,10 +535,10 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
531 535
 
532 536
       // Fill in the Specified Mesh Point
533 537
 
534
-      uint8_t inverted_y = GRID_MAX_POINTS_Y - y_plot - 1;  // The origin is typically in the lower right corner.  We need to
535
-                                                            // invert the Y to get it to plot in the right location.
538
+      const uint8_t y_plot_inv = (GRID_MAX_POINTS_Y - 1) - y_plot;  // The origin is typically in the lower right corner.  We need to
539
+                                                                    // invert the Y to get it to plot in the right location.
536 540
 
537
-      const uint8_t by = y_offset + inverted_y * pixels_per_y_mesh_pnt;
541
+      const u8g_uint_t by = y_offset + y_plot_inv * pixels_per_y_mesh_pnt;
538 542
       if (PAGE_CONTAINS(by, by + pixels_per_y_mesh_pnt))
539 543
         u8g.drawBox(
540 544
           x_offset + x_plot * pixels_per_x_mesh_pnt, by,
@@ -546,26 +550,22 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
546 550
       // Show X and Y positions at top of screen
547 551
       u8g.setColorIndex(1);
548 552
       if (PAGE_UNDER(7)) {
549
-        lcd_moveto(5, 7);
550
-        lcd_put_u8str("X:");
553
+        lcd_put_u8str(5, 7, "X:");
551 554
         lcd_put_u8str(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
552
-        lcd_moveto(74, 7);
553
-        lcd_put_u8str("Y:");
555
+        lcd_put_u8str(74, 7, "Y:");
554 556
         lcd_put_u8str(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
555 557
       }
556 558
 
557 559
       // Print plot position
558 560
       if (PAGE_CONTAINS(LCD_PIXEL_HEIGHT - (INFO_FONT_HEIGHT - 1), LCD_PIXEL_HEIGHT)) {
559
-        lcd_moveto(5, LCD_PIXEL_HEIGHT);
560
-        lcd_put_wchar('(');
561
+        lcd_put_wchar(5, LCD_PIXEL_HEIGHT, '(');
561 562
         u8g.print(x_plot);
562 563
         lcd_put_wchar(',');
563 564
         u8g.print(y_plot);
564 565
         lcd_put_wchar(')');
565 566
 
566 567
         // Show the location value
567
-        lcd_moveto(74, LCD_PIXEL_HEIGHT);
568
-        lcd_put_u8str("Z:");
568
+        lcd_put_u8str(74, LCD_PIXEL_HEIGHT, "Z:");
569 569
         if (!isnan(ubl.z_values[x_plot][y_plot]))
570 570
           lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot]));
571 571
         else

+ 560
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.cpp View File

@@ -0,0 +1,560 @@
1
+/*********************
2
+ * flash_storage.cpp *
3
+ *********************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#include "../compat.h"
24
+
25
+#if ENABLED(LULZBOT_TOUCH_UI)
26
+
27
+#include "../ftdi_eve_lib/ftdi_eve_lib.h"
28
+
29
+#include "media_file_reader.h"
30
+#include "flash_storage.h"
31
+
32
+// The following must be changed whenever the layout of the flash
33
+// data is changed in a manner that would render the data invalid.
34
+
35
+constexpr uint32_t flash_eeprom_version = 1;
36
+
37
+/* SPI Flash Memory Map:
38
+ *
39
+ * The following offsets and sizes are specified in 4k erase units:
40
+ *
41
+ * Page    Size     Description
42
+ * 0       16       DATA STORAGE AREA
43
+ * 16      1        VERSIONING DATA
44
+ * 17      inf      MEDIA STORAGE AREA
45
+ *
46
+ */
47
+
48
+#define DATA_STORAGE_SIZE_64K
49
+
50
+using namespace FTDI::SPI;
51
+using namespace FTDI::SPI::most_significant_byte_first;
52
+
53
+bool UIFlashStorage::is_present = false;
54
+
55
+#ifdef SPI_FLASH_SS
56
+/************************** SPI Flash Chip Interface **************************/
57
+
58
+  void SPIFlash::wait_while_busy() {
59
+    uint8_t status;
60
+    safe_delay(1);
61
+    do {
62
+     spi_flash_select();
63
+     spi_write_8(READ_STATUS_1);
64
+     status = spi_read_8();
65
+     spi_flash_deselect();
66
+     safe_delay(1);
67
+    } while (status & 1);
68
+  }
69
+
70
+  void SPIFlash::erase_sector_4k(uint32_t addr) {
71
+    spi_flash_select();
72
+    spi_write_8(WRITE_ENABLE);
73
+    spi_flash_deselect();
74
+
75
+    spi_flash_select();
76
+    spi_write_8(ERASE_4K);
77
+    spi_write_24(addr);
78
+    spi_flash_deselect();
79
+
80
+    wait_while_busy();
81
+  }
82
+
83
+  void SPIFlash::erase_sector_64k(uint32_t addr) {
84
+    spi_flash_select();
85
+    spi_write_8(WRITE_ENABLE);
86
+    spi_flash_deselect();
87
+
88
+    spi_flash_select();
89
+    spi_write_8(ERASE_64K);
90
+    spi_write_24(addr);
91
+    spi_flash_deselect();
92
+
93
+    wait_while_busy();
94
+  }
95
+
96
+  void SPIFlash::spi_write_begin(uint32_t addr) {
97
+    spi_flash_select();
98
+    spi_write_8(WRITE_ENABLE);
99
+    spi_flash_deselect();
100
+
101
+    spi_flash_select();
102
+    spi_write_8(PAGE_PROGRAM);
103
+    spi_write_24(addr);
104
+  }
105
+
106
+  void SPIFlash::spi_write_end() {
107
+    spi_flash_deselect();
108
+    wait_while_busy();
109
+  }
110
+
111
+  void SPIFlash::spi_read_begin(uint32_t addr) {
112
+    spi_flash_select();
113
+    spi_write_8(READ_DATA);
114
+    spi_write_24(addr);
115
+  }
116
+
117
+  void SPIFlash::spi_read_end() {
118
+    spi_flash_deselect();
119
+  }
120
+
121
+  void SPIFlash::erase_chip() {
122
+    spi_flash_select();
123
+    spi_write_8(WRITE_ENABLE);
124
+    spi_flash_deselect();
125
+
126
+    spi_flash_select();
127
+    spi_write_8(ERASE_CHIP);
128
+    spi_flash_deselect();
129
+    wait_while_busy();
130
+  }
131
+
132
+  void SPIFlash::read_jedec_id(uint8_t &manufacturer_id, uint8_t &device_type, uint8_t &capacity) {
133
+    spi_flash_select();
134
+    spi_write_8(READ_JEDEC_ID);
135
+    manufacturer_id = spi_recv();
136
+    device_type     = spi_recv();
137
+    capacity        = spi_recv();
138
+    spi_flash_deselect ();
139
+  }
140
+
141
+  /* This function writes "size" bytes from "data" starting at addr, while properly
142
+   * taking into account the special case of writing across a 256 byte page boundary.
143
+   * Returns the addr directly after the write.
144
+   */
145
+  uint32_t SPIFlash::write(uint32_t addr, const void *_data, size_t size) {
146
+    const uint8_t *data = (const uint8_t*) _data;
147
+    while (size) {
148
+      const uint32_t page_start = addr & 0xFFFF00ul;
149
+      const uint32_t page_end   = page_start + 256;
150
+      const uint32_t write_size = min(page_end - addr, size);
151
+      spi_write_begin(addr);
152
+      spi_write_bulk<ram_write>(data, write_size);
153
+      spi_write_end();
154
+      addr += write_size;
155
+      size -= write_size;
156
+      data += write_size;
157
+    }
158
+    return addr;
159
+  }
160
+
161
+  uint32_t SPIFlash::read(uint32_t addr, void *data, size_t size) {
162
+    spi_read_begin(addr);
163
+    spi_read_bulk(data, size);
164
+    spi_read_end();
165
+    return addr + size;
166
+  }
167
+
168
+  /********************************** UTILITY ROUTINES *********************************/
169
+
170
+  bool UIFlashStorage::check_known_device() {
171
+    uint8_t manufacturer_id, device_type, capacity;
172
+    read_jedec_id(manufacturer_id, device_type, capacity);
173
+
174
+    const bool is_known =
175
+        ((manufacturer_id == 0xEF) && (device_type == 0x40) && (capacity == 0x15)) || // unknown
176
+        ((manufacturer_id == 0x01) && (device_type == 0x40) && (capacity == 0x15)) || // Cypress S25FL116K
177
+        ((manufacturer_id == 0xEF) && (device_type == 0x14) && (capacity == 0x15)) || // Winbond W25Q16JV
178
+        ((manufacturer_id == 0x1F) && (device_type == 0x86) && (capacity == 0x01)) ;  // Adesto AT255F161
179
+
180
+    if (!is_known) {
181
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Unable to locate supported SPI Flash Memory.");
182
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("  Manufacturer ID, got: ", manufacturer_id);
183
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("  Device Type    , got: ", device_type);
184
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("  Capacity       , got: ", capacity);
185
+    }
186
+
187
+    return is_known;
188
+  }
189
+
190
+  void UIFlashStorage::initialize() {
191
+    for(uint8_t i = 0; i < 10; i++) {
192
+      if (check_known_device()) {
193
+        is_present = true;
194
+        break;
195
+      }
196
+      safe_delay(1000);
197
+    }
198
+  }
199
+
200
+  /**************************** DATA STORAGE AREA (first 4K or 64k) ********************/
201
+
202
+  #ifdef DATA_STORAGE_SIZE_64K
203
+    constexpr uint32_t data_storage_area_size = 64 * 1024; // Large erase unit
204
+  #else
205
+    constexpr uint32_t data_storage_area_size =  4 * 1024; // Small erase unit
206
+  #endif
207
+
208
+  /* In order to provide some degree of wear leveling, each data write to the
209
+   * SPI Flash chip is appended to data that was already written before, until
210
+   * the data storage area is completely filled. New data is written preceeded
211
+   * with a 32-bit delimiter 'LULZ', so that we can distinguish written and
212
+   * unwritten data:
213
+   *
214
+   *        'LULZ'         <--- 1st record delimiter
215
+   *        <data_byte>
216
+   *        <data_byte>
217
+   *        <data_byte>
218
+   *        'LULZ'         <--- 2nd record delimiter
219
+   *        <data_byte>
220
+   *        <data_byte>
221
+   *        <data_byte>
222
+   *           ...
223
+   *        'LULZ'         <--- Last record delimiter
224
+   *        <data_byte>
225
+   *        <data_byte>
226
+   *        <data_byte>
227
+   *        0xFF           <--- Start of free space
228
+   *        0xFF
229
+   *           ...
230
+   *
231
+   * This function walks down the data storage area, verifying that the
232
+   * delimiters are either 'LULZ' or 0xFFFFFFFF. In the case that an invalid
233
+   * delimiter is found, this function returns -1, indicating that the Flash
234
+   * data is invalid (this will happen if the block_size changed with respect
235
+   * to earlier firmware). Otherwise, it returns the offset of the last
236
+   * valid delimiter 'LULZ', indicating the most recently written data.
237
+   */
238
+  int32_t UIFlashStorage::get_config_read_offset(uint32_t block_size) {
239
+    uint16_t stride = 4 + block_size;
240
+    int32_t read_offset = -1;
241
+
242
+    for(uint32_t offset = 0; offset < (data_storage_area_size - stride); offset += stride) {
243
+      uint32_t delim;
244
+      spi_read_begin(offset);
245
+      spi_read_bulk (&delim, sizeof(delim));
246
+      spi_read_end();
247
+      switch (delim) {
248
+        case 0xFFFFFFFFul: return read_offset;
249
+        case delimiter:    read_offset = offset; break;
250
+        default:
251
+          SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("Invalid delimiter in Flash: ", delim);
252
+          return -1;
253
+      }
254
+    }
255
+    SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("No LULZ delimiter found.");
256
+    return -1;
257
+  }
258
+
259
+  /* This function returns the offset at which new data should be
260
+   * appended, or -1 if the Flash needs to be erased */
261
+  int32_t UIFlashStorage::get_config_write_offset(uint32_t block_size) {
262
+    int32_t read_offset = get_config_read_offset(block_size);
263
+    if (read_offset == -1) return -1; // The SPI flash is invalid
264
+
265
+    int32_t write_offset = read_offset + 4 + block_size;
266
+    if ((write_offset + 4 + block_size) > data_storage_area_size) {
267
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Not enough free space in Flash.");
268
+      return -1; // Not enough free space
269
+    }
270
+    return write_offset;
271
+  }
272
+
273
+  bool UIFlashStorage::verify_config_data(const void *data, size_t size) {
274
+    if (!is_present) return false;
275
+
276
+    int32_t read_addr = get_config_read_offset(size);
277
+    if (read_addr == -1) return false;
278
+
279
+    uint32_t delim;
280
+    spi_read_begin(read_addr);
281
+    spi_read_bulk (&delim, sizeof(delim));
282
+    bool ok = spi_verify_bulk(data,size);
283
+    spi_read_end();
284
+    return ok && delim == delimiter;
285
+  }
286
+
287
+  bool UIFlashStorage::read_config_data(void *data, size_t size) {
288
+    if (!is_present) return false;
289
+
290
+    int32_t read_addr = get_config_read_offset(size);
291
+    if (read_addr == -1) return false;
292
+
293
+    uint32_t delim;
294
+    spi_read_begin(read_addr);
295
+    spi_read_bulk (&delim, sizeof(delim));
296
+    spi_read_bulk (data, size);
297
+    spi_read_end();
298
+    return delim == delimiter;
299
+  }
300
+
301
+  void UIFlashStorage::write_config_data(const void *data, size_t size) {
302
+    if (!is_present) {
303
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("SPI Flash chip not present. Not saving UI settings.");
304
+      return;
305
+    }
306
+
307
+    // Since Flash storage has a limited number of write cycles,
308
+    // make sure that the data is different before rewriting.
309
+
310
+    if (verify_config_data(data, size)) {
311
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("UI settings already written, skipping write.");
312
+      return;
313
+    }
314
+
315
+    int16_t write_addr = get_config_write_offset(size);
316
+    if (write_addr == -1) {
317
+      SERIAL_ECHO_START();
318
+      SERIAL_ECHOPGM("Erasing UI settings from SPI Flash... ");
319
+      #ifdef DATA_STORAGE_SIZE_64K
320
+        erase_sector_64k(0);
321
+      #else
322
+        erase_sector_4k(0);
323
+      #endif
324
+      write_addr = 0;
325
+      SERIAL_ECHOLNPGM("DONE");
326
+    }
327
+
328
+    SERIAL_ECHO_START();
329
+    SERIAL_ECHOPAIR("Writing UI settings to SPI Flash (offset ", write_addr);
330
+    SERIAL_ECHOPGM(")...");
331
+
332
+    const uint32_t delim = delimiter;
333
+    write_addr = write(write_addr, &delim, sizeof(delim));
334
+    write_addr = write(write_addr, data, size);
335
+
336
+    SERIAL_ECHOLNPGM("DONE");
337
+  }
338
+
339
+  /************************** VERSIONING INFO AREA ************************/
340
+
341
+  /* The version info area follows the data storage area. If the version
342
+   * is incorrect, the data on the chip is invalid and format_flash should
343
+   * be called.
344
+   */
345
+
346
+  typedef struct {
347
+    uint32_t magic;
348
+    uint32_t version;
349
+  } flash_version_info;
350
+
351
+  constexpr uint32_t version_info_addr = data_storage_area_size;
352
+  constexpr uint32_t version_info_size = 4 * 1024; // Small erase unit
353
+
354
+  bool UIFlashStorage::is_valid() {
355
+    flash_version_info info;
356
+
357
+    spi_read_begin(version_info_addr);
358
+    spi_read_bulk (&info, sizeof(flash_version_info));
359
+    spi_read_end();
360
+
361
+    return info.magic == delimiter && info.version == flash_eeprom_version;
362
+  }
363
+
364
+  void UIFlashStorage::write_version_info() {
365
+    flash_version_info info;
366
+
367
+    info.magic   = delimiter;
368
+    info.version = flash_eeprom_version;
369
+
370
+    spi_write_begin(version_info_addr);
371
+    spi_write_bulk<ram_write>(&info, sizeof(flash_version_info));
372
+    spi_write_end();
373
+  }
374
+
375
+  /**************************** MEDIA STORAGE AREA *****************************/
376
+
377
+  /* The media storage area follows the versioning info area. It consists
378
+   * of a file index followed by the data for one or more media files.
379
+   *
380
+   * The file index consists of an array of 32-bit file sizes. If a file
381
+   * is not present, the file's size will be set to 0xFFFFFFFF
382
+   */
383
+
384
+  constexpr uint32_t media_storage_addr    = version_info_addr + version_info_size;
385
+  constexpr uint8_t  media_storage_slots   = 4;
386
+
387
+  void UIFlashStorage::format_flash() {
388
+    SERIAL_ECHO_START(); SERIAL_ECHOPGM("Erasing SPI Flash...");
389
+    SPIFlash::erase_chip();
390
+    SERIAL_ECHOLNPGM("DONE");
391
+
392
+    write_version_info();
393
+  }
394
+
395
+  uint32_t UIFlashStorage::get_media_file_start(uint8_t slot) {
396
+    uint32_t addr = media_storage_addr + sizeof(uint32_t) * media_storage_slots;
397
+    spi_read_begin(media_storage_addr);
398
+    for(uint8_t i = 0; i < slot; i++) {
399
+      addr += spi_read_32();
400
+    }
401
+    spi_read_end();
402
+    return addr;
403
+  }
404
+
405
+  void UIFlashStorage::set_media_file_size(uint8_t slot, uint32_t size) {
406
+    spi_write_begin(media_storage_addr + sizeof(uint32_t) * slot);
407
+    spi_write_32(size);
408
+    spi_write_end();
409
+  }
410
+
411
+  uint32_t UIFlashStorage::get_media_file_size(uint8_t slot) {
412
+    spi_read_begin(media_storage_addr + sizeof(uint32_t) * slot);
413
+    uint32_t size = spi_read_32();
414
+    spi_read_end();
415
+    return size;
416
+  }
417
+
418
+  /* Writes a media file from the SD card/USB flash drive into a slot on the SPI Flash. Media
419
+   * files must be written sequentially following by a chip erase and it is not possible to
420
+   * overwrite files. */
421
+  UIFlashStorage::error_t UIFlashStorage::write_media_file(progmem_str filename, uint8_t slot) {
422
+    #if ENABLED(SDSUPPORT)
423
+      uint32_t addr;
424
+      uint8_t buff[write_page_size];
425
+
426
+      strcpy_P( (char*) buff, (const char*) filename);
427
+
428
+      MediaFileReader reader;
429
+      if (!reader.open((char*) buff)) {
430
+        SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Unable to find media file");
431
+        return FILE_NOT_FOUND;
432
+      }
433
+
434
+      if (get_media_file_size(slot) != 0xFFFFFFFFUL) {
435
+        SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Media file already exists");
436
+        return WOULD_OVERWRITE;
437
+      }
438
+
439
+      SERIAL_ECHO_START(); SERIAL_ECHOPGM("Writing SPI Flash...");
440
+
441
+      set_media_file_size(slot, reader.size());
442
+      addr = get_media_file_start(slot);
443
+
444
+      // Write out the file itself
445
+      for(;;) {
446
+        const int16_t nBytes = reader.read(buff, write_page_size);
447
+        if (nBytes == -1) {
448
+          SERIAL_ECHOLNPGM("Failed to read from file");
449
+          return READ_ERROR;
450
+        }
451
+
452
+        addr = write(addr, buff, nBytes);
453
+        if (nBytes != write_page_size)
454
+          break;
455
+
456
+        #if ENABLED(EXTENSIBLE_UI)
457
+          ExtUI::yield();
458
+        #endif
459
+      }
460
+
461
+      SERIAL_ECHOLNPGM("DONE");
462
+
463
+      SERIAL_ECHO_START(); SERIAL_ECHOPGM("Verifying SPI Flash...");
464
+
465
+      bool verifyOk = true;
466
+
467
+      // Verify the file index
468
+
469
+      if (get_media_file_start(slot+1) != (get_media_file_start(slot) + reader.size())) {
470
+        SERIAL_ECHOLNPGM("File index verification failed. ");
471
+        verifyOk = false;
472
+      }
473
+
474
+      // Verify the file itself
475
+      addr = get_media_file_start(slot);
476
+      reader.rewind();
477
+
478
+      while (verifyOk) {
479
+        const int16_t nBytes = reader.read(buff, write_page_size);
480
+        if (nBytes == -1) {
481
+          SERIAL_ECHOPGM("Failed to read from file");
482
+          verifyOk = false;
483
+          break;
484
+        }
485
+
486
+        spi_read_begin(addr);
487
+        if (!spi_verify_bulk(buff, nBytes)) {
488
+          verifyOk = false;
489
+          spi_read_end();
490
+          break;
491
+        }
492
+        spi_read_end();
493
+
494
+        addr += nBytes;
495
+        if (nBytes != write_page_size) break;
496
+        #if ENABLED(EXTENSIBLE_UI)
497
+          ExtUI::yield();
498
+        #endif
499
+      };
500
+
501
+      if (verifyOk) {
502
+        SERIAL_ECHOLNPGM("DONE");
503
+        return SUCCESS;
504
+      } else {
505
+        SERIAL_ECHOLNPGM("FAIL");
506
+        return VERIFY_ERROR;
507
+      }
508
+    #else
509
+      return VERIFY_ERROR;
510
+    #endif // ENABLED(SDSUPPORT)
511
+  }
512
+
513
+  bool UIFlashStorage::BootMediaReader::isAvailable(uint32_t slot) {
514
+    if (!is_present) return false;
515
+
516
+    bytes_remaining = get_media_file_size(slot);
517
+    if (bytes_remaining != 0xFFFFFFFFUL) {
518
+      SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("Boot media file size:", bytes_remaining);
519
+      addr = get_media_file_start(slot);
520
+      return true;
521
+    } else {
522
+      return false;
523
+    }
524
+  }
525
+
526
+  int16_t UIFlashStorage::BootMediaReader::read(void *data, const size_t size) {
527
+    if (bytes_remaining == 0xFFFFFFFFUL) return -1;
528
+
529
+    if (size > bytes_remaining)
530
+      return read(data, bytes_remaining);
531
+
532
+    if (size > 0) {
533
+      spi_read_begin(addr);
534
+      spi_read_bulk(data, size);
535
+      spi_read_end();
536
+      addr += size;
537
+      bytes_remaining -= size;
538
+    }
539
+
540
+    return size;
541
+  }
542
+
543
+  int16_t UIFlashStorage::BootMediaReader::read(void *obj, void *data, const size_t size) {
544
+    return reinterpret_cast<UIFlashStorage::BootMediaReader*>(obj)->read(data, size);
545
+  }
546
+
547
+#else
548
+  void UIFlashStorage::initialize()                                           {}
549
+  bool UIFlashStorage::is_valid()                                             {return true;}
550
+  void UIFlashStorage::write_config_data(const void *, size_t)                {}
551
+  bool UIFlashStorage::verify_config_data(const void *, size_t)               {return false;}
552
+  bool UIFlashStorage::read_config_data(void *, size_t )                      {return false;}
553
+  UIFlashStorage::error_t UIFlashStorage::write_media_file(progmem_str, uint8_t) {return FILE_NOT_FOUND;}
554
+  void UIFlashStorage::format_flash()                                         {}
555
+
556
+  bool UIFlashStorage::BootMediaReader::isAvailable(uint32_t)                 {return false;}
557
+  int16_t UIFlashStorage::BootMediaReader::read(void *, const size_t)         {return -1;}
558
+  int16_t UIFlashStorage::BootMediaReader::read(void *, void *, const size_t) {return -1;}
559
+#endif // SPI_FLASH_SS
560
+#endif // LULZBOT_TOUCH_UI

+ 106
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.h View File

@@ -0,0 +1,106 @@
1
+/*******************
2
+ * flash_storage.h *
3
+ *******************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+class SPIFlash {
24
+  public:
25
+    static constexpr uint32_t erase_unit_size = 4 * 1024; // Minimum erase unit
26
+    static constexpr uint32_t write_page_size = 256;      // Minimum page write unit
27
+
28
+    enum {
29
+      READ_STATUS_1 = 0x05,
30
+      READ_STATUS_2 = 0x35,
31
+      READ_STATUS_3 = 0x33,
32
+      WRITE_ENABLE  = 0x06,
33
+      WRITE_DISABLE = 0x04,
34
+      READ_ID       = 0x90,
35
+      READ_JEDEC_ID = 0x9F,
36
+      READ_DATA     = 0x03,
37
+      PAGE_PROGRAM  = 0x02,
38
+      ERASE_4K      = 0x20,
39
+      ERASE_64K     = 0xD8,
40
+      ERASE_CHIP    = 0xC7
41
+    };
42
+
43
+    static void wait_while_busy();
44
+    static void erase_sector_4k(uint32_t addr);
45
+    static void erase_sector_64k(uint32_t addr);
46
+    static void erase_chip  ();
47
+
48
+    static void read_jedec_id(uint8_t &manufacturer_id, uint8_t &device_type, uint8_t &capacity);
49
+
50
+    static void spi_read_begin(uint32_t addr);
51
+    static void spi_read_end();
52
+
53
+    static void spi_write_begin(uint32_t addr);
54
+    static void spi_write_end();
55
+
56
+    static uint32_t write(uint32_t addr, const void *data, size_t size);
57
+    static uint32_t read(uint32_t addr, void *data, size_t size);
58
+};
59
+
60
+class UIFlashStorage : private SPIFlash {
61
+  private:
62
+
63
+    static bool is_present;
64
+    static int32_t  get_config_read_offset(uint32_t block_size);
65
+    static int32_t  get_config_write_offset(uint32_t block_size);
66
+
67
+    static uint32_t get_media_file_start(uint8_t slot);
68
+    static void     set_media_file_size(uint8_t slot, uint32_t size);
69
+    static uint32_t get_media_file_size(uint8_t slot);
70
+
71
+    static constexpr uint32_t delimiter = 0x4C554C5A; // 'LULZ'
72
+  public:
73
+    enum error_t {
74
+      SUCCESS,
75
+      FILE_NOT_FOUND,
76
+      READ_ERROR,
77
+      VERIFY_ERROR,
78
+      WOULD_OVERWRITE
79
+    };
80
+
81
+    static void    initialize  ();
82
+    static void    format_flash ();
83
+    static bool    check_known_device();
84
+
85
+    static bool    is_valid ();
86
+    static void    write_version_info();
87
+
88
+    static void    write_config_data  (const void *data, size_t size);
89
+    static bool    verify_config_data (const void *data, size_t size);
90
+    static bool    read_config_data   (void *data, size_t size);
91
+    static error_t write_media_file   (progmem_str filename, uint8_t slot = 0);
92
+
93
+    class BootMediaReader;
94
+};
95
+
96
+class UIFlashStorage::BootMediaReader {
97
+  private:
98
+    uint32_t addr;
99
+    uint32_t bytes_remaining;
100
+
101
+  public:
102
+    bool isAvailable(uint32_t slot = 0);
103
+    int16_t read(void *buffer, size_t const size);
104
+
105
+    static int16_t read(void *obj, void *buffer, const size_t size);
106
+};

+ 63
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.cpp View File

@@ -0,0 +1,63 @@
1
+/************************
2
+ * media_filereader.cpp *
3
+ ************************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#include "../compat.h"
24
+
25
+#if ENABLED(LULZBOT_TOUCH_UI)
26
+  #include "media_file_reader.h"
27
+
28
+  #if ENABLED(SDSUPPORT)
29
+    bool MediaFileReader::open(const char* filename) {
30
+      card.init(SPI_SPEED, SDSS);
31
+      volume.init(&card);
32
+      root.openRoot(&volume);
33
+      return file.open(&root, filename, O_READ);
34
+    }
35
+
36
+    int16_t MediaFileReader::read(void *buff, size_t bytes) {
37
+      return file.read(buff, bytes);
38
+    }
39
+
40
+    void MediaFileReader::close() {
41
+      file.close();
42
+    }
43
+
44
+    uint32_t MediaFileReader::size() {
45
+      return file.fileSize();
46
+    }
47
+
48
+    void MediaFileReader::rewind() {
49
+      file.rewind();
50
+    }
51
+
52
+    int16_t MediaFileReader::read(void *obj, void *buff, size_t bytes) {
53
+      return reinterpret_cast<MediaFileReader*>(obj)->read(buff, bytes);
54
+    }
55
+  #else
56
+    bool MediaFileReader::open(const char*)               {return -1;}
57
+    int16_t MediaFileReader::read(void *, size_t)         {return 0;}
58
+    void MediaFileReader::close()                         {}
59
+    uint32_t MediaFileReader::size()                      {return 0;}
60
+    void MediaFileReader::rewind()                        {}
61
+    int16_t MediaFileReader::read(void *, void *, size_t) {return 0;}
62
+  #endif
63
+#endif // LULZBOT_TOUCH_UI

+ 48
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.h View File

@@ -0,0 +1,48 @@
1
+/**********************
2
+ * media_filereader.h *
3
+ **********************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+#include "../../../../../inc/MarlinConfigPre.h"
26
+
27
+#if ENABLED(SDSUPPORT)
28
+  #include "../../../../../sd/SdFile.h"
29
+  #include "../../../../../sd/cardreader.h"
30
+#endif
31
+
32
+class MediaFileReader {
33
+  private:
34
+    #if ENABLED(SDSUPPORT)
35
+      Sd2Card  card;
36
+      SdVolume volume;
37
+      SdFile   root, file;
38
+    #endif
39
+
40
+  public:
41
+    bool open(const char* filename);
42
+    int16_t read(void *buff, size_t bytes);
43
+    uint32_t size();
44
+    void rewind();
45
+    void close();
46
+
47
+    static int16_t read(void *obj, void *buff, size_t bytes);
48
+};

+ 53
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/compat.h View File

@@ -0,0 +1,53 @@
1
+/************
2
+ * compat.h *
3
+ ************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+/**
25
+ * This following provides compatibility whether compiling
26
+ * as a part of Marlin or outside it
27
+ */
28
+
29
+#if defined __has_include
30
+  #if __has_include ("../../ui_api.h")
31
+    #include "../../ui_api.h"
32
+  #endif
33
+#else
34
+  #include "../../ui_api.h"
35
+#endif
36
+
37
+#ifdef __MARLIN_FIRMWARE__
38
+  // __MARLIN_FIRMWARE__ exists when compiled within Marlin.
39
+  #include "pin_mappings.h"
40
+#else
41
+  // Messages that are declared in Marlin
42
+  #define WELCOME_MSG        "Printer Ready"
43
+  #define MSG_MEDIA_INSERTED "Media Inserted"
44
+  #define MSG_MEDIA_REMOVED  "Media Removed"
45
+
46
+  namespace UI {
47
+    static inline uint32_t safe_millis() {return millis();};
48
+    static inline void     yield()       {};
49
+  };
50
+#endif
51
+
52
+class __FlashStringHelper;
53
+typedef const __FlashStringHelper *progmem_str;

+ 97
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/config.h View File

@@ -0,0 +1,97 @@
1
+/************
2
+ * config.h *
3
+ ************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+#include "compat.h"
25
+
26
+// Define the display board used (see "ftdi_eve_boards.h" for definitions)
27
+
28
+//#define LCD_FTDI_VM800B35A        // FTDI 3.5" 320x240 with FT800
29
+//#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" 480x272
30
+//#define LCD_HAOYU_FT800CB         // Haoyu with 4.3" or 5" 480x272
31
+//#define LCD_HAOYU_FT810CB         // Haoyu with 5" 800x480
32
+//#define LCD_ALEPHOBJECTS_CLCD_UI  // Aleph Objects Color LCD User Interface
33
+
34
+// Leave the following commented out to use a board's default resolution.
35
+// If you have changed the LCD panel, you may override the resolution
36
+// below (see "ftdi_eve_resolutions.h" for definitions):
37
+
38
+//#define TOUCH_UI_320x240
39
+//#define TOUCH_UI_480x272
40
+//#define TOUCH_UI_800x480
41
+
42
+// Define the printer interface or pins used (see "ui_pin_mappings.h" for definitions):
43
+
44
+//#define CR10_TFT_PINMAP
45
+//#define AO_EXP1_DEPRECATED_PINMAP  // UltraLCD EXP1 connector, old AlephObject's wiring
46
+//#define AO_EXP1_PINMAP  // UltraLCD EXP1 connector, new AlephObject's wiring
47
+//#define AO_EXP2_PINMAP  // UltraLCD EXP2 connector, new AlephObject's wiring
48
+//#define OTHER_PIN_LAYOUT
49
+
50
+// Otherwise. Define all the pins manually:
51
+
52
+#ifdef OTHER_PIN_LAYOUT
53
+    // Select interfacing pins, the following pin specifiers are supported:
54
+    //
55
+    //     ARDUINO_DIGITAL_1  - Arduino pin via digitalWrite/digitalRead
56
+    //     AVR_A1             - Fast AVR port access via PORTA/PINA/DDRA
57
+    //     1                  - When compiling Marlin, use Marlin pin IDs.
58
+
59
+    // The pins for CS and MOD_RESET (PD) must be chosen.
60
+    #define CLCD_MOD_RESET                      9
61
+    #define CLCD_SPI_CS                        10
62
+
63
+    // If using software SPI, specify pins for SCLK, MOSI, MISO
64
+    //#define CLCD_USE_SOFT_SPI
65
+    #ifdef CLCD_USE_SOFT_SPI
66
+        #define CLCD_SOFT_SPI_MOSI             11
67
+        #define CLCD_SOFT_SPI_MISO             12
68
+        #define CLCD_SOFT_SPI_SCLK             13
69
+    #endif
70
+#endif
71
+
72
+// Defines how to orient the display. An inverted (i.e. upside-down) display
73
+// is supported on the FT800. The FT810 or better also support a portrait
74
+// and mirrored orientation.
75
+//#define TOUCH_UI_INVERTED
76
+//#define TOUCH_UI_PORTRAIT
77
+//#define TOUCH_UI_MIRRORED
78
+
79
+// Use a numeric passcode for "Parental lock".
80
+// This is a recommended for smaller displays.
81
+//#define TOUCH_UI_PASSCODE
82
+
83
+// The timeout (in ms) to return to the status screen from sub-menus
84
+//#define LCD_TIMEOUT_TO_STATUS 15000
85
+
86
+// Enable this to debug the event framework
87
+//#define UI_FRAMEWORK_DEBUG
88
+
89
+// Enable the developer's menu and screens
90
+//#define DEVELOPER_SCREENS
91
+
92
+// Maximum feed rate for manual extrusion (mm/s)
93
+//#define MAX_MANUAL_FEEDRATE 240
94
+
95
+// Sets the SPI speed in Hz
96
+
97
+#define SPI_FREQUENCY 8000000 >> SPI_SPEED

+ 674
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/LICENSE.txt View File

@@ -0,0 +1,674 @@
1
+                    GNU GENERAL PUBLIC LICENSE
2
+                       Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+                            Preamble
9
+
10
+  The GNU General Public License is a free, copyleft license for
11
+software and other kinds of works.
12
+
13
+  The licenses for most software and other practical works are designed
14
+to take away your freedom to share and change the works.  By contrast,
15
+the GNU General Public License is intended to guarantee your freedom to
16
+share and change all versions of a program--to make sure it remains free
17
+software for all its users.  We, the Free Software Foundation, use the
18
+GNU General Public License for most of our software; it applies also to
19
+any other work released this way by its authors.  You can apply it to
20
+your programs, too.
21
+
22
+  When we speak of free software, we are referring to freedom, not
23
+price.  Our General Public Licenses are designed to make sure that you
24
+have the freedom to distribute copies of free software (and charge for
25
+them if you wish), that you receive source code or can get it if you
26
+want it, that you can change the software or use pieces of it in new
27
+free programs, and that you know you can do these things.
28
+
29
+  To protect your rights, we need to prevent others from denying you
30
+these rights or asking you to surrender the rights.  Therefore, you have
31
+certain responsibilities if you distribute copies of the software, or if
32
+you modify it: responsibilities to respect the freedom of others.
33
+
34
+  For example, if you distribute copies of such a program, whether
35
+gratis or for a fee, you must pass on to the recipients the same
36
+freedoms that you received.  You must make sure that they, too, receive
37
+or can get the source code.  And you must show them these terms so they
38
+know their rights.
39
+
40
+  Developers that use the GNU GPL protect your rights with two steps:
41
+(1) assert copyright on the software, and (2) offer you this License
42
+giving you legal permission to copy, distribute and/or modify it.
43
+
44
+  For the developers' and authors' protection, the GPL clearly explains
45
+that there is no warranty for this free software.  For both users' and
46
+authors' sake, the GPL requires that modified versions be marked as
47
+changed, so that their problems will not be attributed erroneously to
48
+authors of previous versions.
49
+
50
+  Some devices are designed to deny users access to install or run
51
+modified versions of the software inside them, although the manufacturer
52
+can do so.  This is fundamentally incompatible with the aim of
53
+protecting users' freedom to change the software.  The systematic
54
+pattern of such abuse occurs in the area of products for individuals to
55
+use, which is precisely where it is most unacceptable.  Therefore, we
56
+have designed this version of the GPL to prohibit the practice for those
57
+products.  If such problems arise substantially in other domains, we
58
+stand ready to extend this provision to those domains in future versions
59
+of the GPL, as needed to protect the freedom of users.
60
+
61
+  Finally, every program is threatened constantly by software patents.
62
+States should not allow patents to restrict development and use of
63
+software on general-purpose computers, but in those that do, we wish to
64
+avoid the special danger that patents applied to a free program could
65
+make it effectively proprietary.  To prevent this, the GPL assures that
66
+patents cannot be used to render the program non-free.
67
+
68
+  The precise terms and conditions for copying, distribution and
69
+modification follow.
70
+
71
+                       TERMS AND CONDITIONS
72
+
73
+  0. Definitions.
74
+
75
+  "This License" refers to version 3 of the GNU General Public License.
76
+
77
+  "Copyright" also means copyright-like laws that apply to other kinds of
78
+works, such as semiconductor masks.
79
+
80
+  "The Program" refers to any copyrightable work licensed under this
81
+License.  Each licensee is addressed as "you".  "Licensees" and
82
+"recipients" may be individuals or organizations.
83
+
84
+  To "modify" a work means to copy from or adapt all or part of the work
85
+in a fashion requiring copyright permission, other than the making of an
86
+exact copy.  The resulting work is called a "modified version" of the
87
+earlier work or a work "based on" the earlier work.
88
+
89
+  A "covered work" means either the unmodified Program or a work based
90
+on the Program.
91
+
92
+  To "propagate" a work means to do anything with it that, without
93
+permission, would make you directly or secondarily liable for
94
+infringement under applicable copyright law, except executing it on a
95
+computer or modifying a private copy.  Propagation includes copying,
96
+distribution (with or without modification), making available to the
97
+public, and in some countries other activities as well.
98
+
99
+  To "convey" a work means any kind of propagation that enables other
100
+parties to make or receive copies.  Mere interaction with a user through
101
+a computer network, with no transfer of a copy, is not conveying.
102
+
103
+  An interactive user interface displays "Appropriate Legal Notices"
104
+to the extent that it includes a convenient and prominently visible
105
+feature that (1) displays an appropriate copyright notice, and (2)
106
+tells the user that there is no warranty for the work (except to the
107
+extent that warranties are provided), that licensees may convey the
108
+work under this License, and how to view a copy of this License.  If
109
+the interface presents a list of user commands or options, such as a
110
+menu, a prominent item in the list meets this criterion.
111
+
112
+  1. Source Code.
113
+
114
+  The "source code" for a work means the preferred form of the work
115
+for making modifications to it.  "Object code" means any non-source
116
+form of a work.
117
+
118
+  A "Standard Interface" means an interface that either is an official
119
+standard defined by a recognized standards body, or, in the case of
120
+interfaces specified for a particular programming language, one that
121
+is widely used among developers working in that language.
122
+
123
+  The "System Libraries" of an executable work include anything, other
124
+than the work as a whole, that (a) is included in the normal form of
125
+packaging a Major Component, but which is not part of that Major
126
+Component, and (b) serves only to enable use of the work with that
127
+Major Component, or to implement a Standard Interface for which an
128
+implementation is available to the public in source code form.  A
129
+"Major Component", in this context, means a major essential component
130
+(kernel, window system, and so on) of the specific operating system
131
+(if any) on which the executable work runs, or a compiler used to
132
+produce the work, or an object code interpreter used to run it.
133
+
134
+  The "Corresponding Source" for a work in object code form means all
135
+the source code needed to generate, install, and (for an executable
136
+work) run the object code and to modify the work, including scripts to
137
+control those activities.  However, it does not include the work's
138
+System Libraries, or general-purpose tools or generally available free
139
+programs which are used unmodified in performing those activities but
140
+which are not part of the work.  For example, Corresponding Source
141
+includes interface definition files associated with source files for
142
+the work, and the source code for shared libraries and dynamically
143
+linked subprograms that the work is specifically designed to require,
144
+such as by intimate data communication or control flow between those
145
+subprograms and other parts of the work.
146
+
147
+  The Corresponding Source need not include anything that users
148
+can regenerate automatically from other parts of the Corresponding
149
+Source.
150
+
151
+  The Corresponding Source for a work in source code form is that
152
+same work.
153
+
154
+  2. Basic Permissions.
155
+
156
+  All rights granted under this License are granted for the term of
157
+copyright on the Program, and are irrevocable provided the stated
158
+conditions are met.  This License explicitly affirms your unlimited
159
+permission to run the unmodified Program.  The output from running a
160
+covered work is covered by this License only if the output, given its
161
+content, constitutes a covered work.  This License acknowledges your
162
+rights of fair use or other equivalent, as provided by copyright law.
163
+
164
+  You may make, run and propagate covered works that you do not
165
+convey, without conditions so long as your license otherwise remains
166
+in force.  You may convey covered works to others for the sole purpose
167
+of having them make modifications exclusively for you, or provide you
168
+with facilities for running those works, provided that you comply with
169
+the terms of this License in conveying all material for which you do
170
+not control copyright.  Those thus making or running the covered works
171
+for you must do so exclusively on your behalf, under your direction
172
+and control, on terms that prohibit them from making any copies of
173
+your copyrighted material outside their relationship with you.
174
+
175
+  Conveying under any other circumstances is permitted solely under
176
+the conditions stated below.  Sublicensing is not allowed; section 10
177
+makes it unnecessary.
178
+
179
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
+
181
+  No covered work shall be deemed part of an effective technological
182
+measure under any applicable law fulfilling obligations under article
183
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
184
+similar laws prohibiting or restricting circumvention of such
185
+measures.
186
+
187
+  When you convey a covered work, you waive any legal power to forbid
188
+circumvention of technological measures to the extent such circumvention
189
+is effected by exercising rights under this License with respect to
190
+the covered work, and you disclaim any intention to limit operation or
191
+modification of the work as a means of enforcing, against the work's
192
+users, your or third parties' legal rights to forbid circumvention of
193
+technological measures.
194
+
195
+  4. Conveying Verbatim Copies.
196
+
197
+  You may convey verbatim copies of the Program's source code as you
198
+receive it, in any medium, provided that you conspicuously and
199
+appropriately publish on each copy an appropriate copyright notice;
200
+keep intact all notices stating that this License and any
201
+non-permissive terms added in accord with section 7 apply to the code;
202
+keep intact all notices of the absence of any warranty; and give all
203
+recipients a copy of this License along with the Program.
204
+
205
+  You may charge any price or no price for each copy that you convey,
206
+and you may offer support or warranty protection for a fee.
207
+
208
+  5. Conveying Modified Source Versions.
209
+
210
+  You may convey a work based on the Program, or the modifications to
211
+produce it from the Program, in the form of source code under the
212
+terms of section 4, provided that you also meet all of these conditions:
213
+
214
+    a) The work must carry prominent notices stating that you modified
215
+    it, and giving a relevant date.
216
+
217
+    b) The work must carry prominent notices stating that it is
218
+    released under this License and any conditions added under section
219
+    7.  This requirement modifies the requirement in section 4 to
220
+    "keep intact all notices".
221
+
222
+    c) You must license the entire work, as a whole, under this
223
+    License to anyone who comes into possession of a copy.  This
224
+    License will therefore apply, along with any applicable section 7
225
+    additional terms, to the whole of the work, and all its parts,
226
+    regardless of how they are packaged.  This License gives no
227
+    permission to license the work in any other way, but it does not
228
+    invalidate such permission if you have separately received it.
229
+
230
+    d) If the work has interactive user interfaces, each must display
231
+    Appropriate Legal Notices; however, if the Program has interactive
232
+    interfaces that do not display Appropriate Legal Notices, your
233
+    work need not make them do so.
234
+
235
+  A compilation of a covered work with other separate and independent
236
+works, which are not by their nature extensions of the covered work,
237
+and which are not combined with it such as to form a larger program,
238
+in or on a volume of a storage or distribution medium, is called an
239
+"aggregate" if the compilation and its resulting copyright are not
240
+used to limit the access or legal rights of the compilation's users
241
+beyond what the individual works permit.  Inclusion of a covered work
242
+in an aggregate does not cause this License to apply to the other
243
+parts of the aggregate.
244
+
245
+  6. Conveying Non-Source Forms.
246
+
247
+  You may convey a covered work in object code form under the terms
248
+of sections 4 and 5, provided that you also convey the
249
+machine-readable Corresponding Source under the terms of this License,
250
+in one of these ways:
251
+
252
+    a) Convey the object code in, or embodied in, a physical product
253
+    (including a physical distribution medium), accompanied by the
254
+    Corresponding Source fixed on a durable physical medium
255
+    customarily used for software interchange.
256
+
257
+    b) Convey the object code in, or embodied in, a physical product
258
+    (including a physical distribution medium), accompanied by a
259
+    written offer, valid for at least three years and valid for as
260
+    long as you offer spare parts or customer support for that product
261
+    model, to give anyone who possesses the object code either (1) a
262
+    copy of the Corresponding Source for all the software in the
263
+    product that is covered by this License, on a durable physical
264
+    medium customarily used for software interchange, for a price no
265
+    more than your reasonable cost of physically performing this
266
+    conveying of source, or (2) access to copy the
267
+    Corresponding Source from a network server at no charge.
268
+
269
+    c) Convey individual copies of the object code with a copy of the
270
+    written offer to provide the Corresponding Source.  This
271
+    alternative is allowed only occasionally and noncommercially, and
272
+    only if you received the object code with such an offer, in accord
273
+    with subsection 6b.
274
+
275
+    d) Convey the object code by offering access from a designated
276
+    place (gratis or for a charge), and offer equivalent access to the
277
+    Corresponding Source in the same way through the same place at no
278
+    further charge.  You need not require recipients to copy the
279
+    Corresponding Source along with the object code.  If the place to
280
+    copy the object code is a network server, the Corresponding Source
281
+    may be on a different server (operated by you or a third party)
282
+    that supports equivalent copying facilities, provided you maintain
283
+    clear directions next to the object code saying where to find the
284
+    Corresponding Source.  Regardless of what server hosts the
285
+    Corresponding Source, you remain obligated to ensure that it is
286
+    available for as long as needed to satisfy these requirements.
287
+
288
+    e) Convey the object code using peer-to-peer transmission, provided
289
+    you inform other peers where the object code and Corresponding
290
+    Source of the work are being offered to the general public at no
291
+    charge under subsection 6d.
292
+
293
+  A separable portion of the object code, whose source code is excluded
294
+from the Corresponding Source as a System Library, need not be
295
+included in conveying the object code work.
296
+
297
+  A "User Product" is either (1) a "consumer product", which means any
298
+tangible personal property which is normally used for personal, family,
299
+or household purposes, or (2) anything designed or sold for incorporation
300
+into a dwelling.  In determining whether a product is a consumer product,
301
+doubtful cases shall be resolved in favor of coverage.  For a particular
302
+product received by a particular user, "normally used" refers to a
303
+typical or common use of that class of product, regardless of the status
304
+of the particular user or of the way in which the particular user
305
+actually uses, or expects or is expected to use, the product.  A product
306
+is a consumer product regardless of whether the product has substantial
307
+commercial, industrial or non-consumer uses, unless such uses represent
308
+the only significant mode of use of the product.
309
+
310
+  "Installation Information" for a User Product means any methods,
311
+procedures, authorization keys, or other information required to install
312
+and execute modified versions of a covered work in that User Product from
313
+a modified version of its Corresponding Source.  The information must
314
+suffice to ensure that the continued functioning of the modified object
315
+code is in no case prevented or interfered with solely because
316
+modification has been made.
317
+
318
+  If you convey an object code work under this section in, or with, or
319
+specifically for use in, a User Product, and the conveying occurs as
320
+part of a transaction in which the right of possession and use of the
321
+User Product is transferred to the recipient in perpetuity or for a
322
+fixed term (regardless of how the transaction is characterized), the
323
+Corresponding Source conveyed under this section must be accompanied
324
+by the Installation Information.  But this requirement does not apply
325
+if neither you nor any third party retains the ability to install
326
+modified object code on the User Product (for example, the work has
327
+been installed in ROM).
328
+
329
+  The requirement to provide Installation Information does not include a
330
+requirement to continue to provide support service, warranty, or updates
331
+for a work that has been modified or installed by the recipient, or for
332
+the User Product in which it has been modified or installed.  Access to a
333
+network may be denied when the modification itself materially and
334
+adversely affects the operation of the network or violates the rules and
335
+protocols for communication across the network.
336
+
337
+  Corresponding Source conveyed, and Installation Information provided,
338
+in accord with this section must be in a format that is publicly
339
+documented (and with an implementation available to the public in
340
+source code form), and must require no special password or key for
341
+unpacking, reading or copying.
342
+
343
+  7. Additional Terms.
344
+
345
+  "Additional permissions" are terms that supplement the terms of this
346
+License by making exceptions from one or more of its conditions.
347
+Additional permissions that are applicable to the entire Program shall
348
+be treated as though they were included in this License, to the extent
349
+that they are valid under applicable law.  If additional permissions
350
+apply only to part of the Program, that part may be used separately
351
+under those permissions, but the entire Program remains governed by
352
+this License without regard to the additional permissions.
353
+
354
+  When you convey a copy of a covered work, you may at your option
355
+remove any additional permissions from that copy, or from any part of
356
+it.  (Additional permissions may be written to require their own
357
+removal in certain cases when you modify the work.)  You may place
358
+additional permissions on material, added by you to a covered work,
359
+for which you have or can give appropriate copyright permission.
360
+
361
+  Notwithstanding any other provision of this License, for material you
362
+add to a covered work, you may (if authorized by the copyright holders of
363
+that material) supplement the terms of this License with terms:
364
+
365
+    a) Disclaiming warranty or limiting liability differently from the
366
+    terms of sections 15 and 16 of this License; or
367
+
368
+    b) Requiring preservation of specified reasonable legal notices or
369
+    author attributions in that material or in the Appropriate Legal
370
+    Notices displayed by works containing it; or
371
+
372
+    c) Prohibiting misrepresentation of the origin of that material, or
373
+    requiring that modified versions of such material be marked in
374
+    reasonable ways as different from the original version; or
375
+
376
+    d) Limiting the use for publicity purposes of names of licensors or
377
+    authors of the material; or
378
+
379
+    e) Declining to grant rights under trademark law for use of some
380
+    trade names, trademarks, or service marks; or
381
+
382
+    f) Requiring indemnification of licensors and authors of that
383
+    material by anyone who conveys the material (or modified versions of
384
+    it) with contractual assumptions of liability to the recipient, for
385
+    any liability that these contractual assumptions directly impose on
386
+    those licensors and authors.
387
+
388
+  All other non-permissive additional terms are considered "further
389
+restrictions" within the meaning of section 10.  If the Program as you
390
+received it, or any part of it, contains a notice stating that it is
391
+governed by this License along with a term that is a further
392
+restriction, you may remove that term.  If a license document contains
393
+a further restriction but permits relicensing or conveying under this
394
+License, you may add to a covered work material governed by the terms
395
+of that license document, provided that the further restriction does
396
+not survive such relicensing or conveying.
397
+
398
+  If you add terms to a covered work in accord with this section, you
399
+must place, in the relevant source files, a statement of the
400
+additional terms that apply to those files, or a notice indicating
401
+where to find the applicable terms.
402
+
403
+  Additional terms, permissive or non-permissive, may be stated in the
404
+form of a separately written license, or stated as exceptions;
405
+the above requirements apply either way.
406
+
407
+  8. Termination.
408
+
409
+  You may not propagate or modify a covered work except as expressly
410
+provided under this License.  Any attempt otherwise to propagate or
411
+modify it is void, and will automatically terminate your rights under
412
+this License (including any patent licenses granted under the third
413
+paragraph of section 11).
414
+
415
+  However, if you cease all violation of this License, then your
416
+license from a particular copyright holder is reinstated (a)
417
+provisionally, unless and until the copyright holder explicitly and
418
+finally terminates your license, and (b) permanently, if the copyright
419
+holder fails to notify you of the violation by some reasonable means
420
+prior to 60 days after the cessation.
421
+
422
+  Moreover, your license from a particular copyright holder is
423
+reinstated permanently if the copyright holder notifies you of the
424
+violation by some reasonable means, this is the first time you have
425
+received notice of violation of this License (for any work) from that
426
+copyright holder, and you cure the violation prior to 30 days after
427
+your receipt of the notice.
428
+
429
+  Termination of your rights under this section does not terminate the
430
+licenses of parties who have received copies or rights from you under
431
+this License.  If your rights have been terminated and not permanently
432
+reinstated, you do not qualify to receive new licenses for the same
433
+material under section 10.
434
+
435
+  9. Acceptance Not Required for Having Copies.
436
+
437
+  You are not required to accept this License in order to receive or
438
+run a copy of the Program.  Ancillary propagation of a covered work
439
+occurring solely as a consequence of using peer-to-peer transmission
440
+to receive a copy likewise does not require acceptance.  However,
441
+nothing other than this License grants you permission to propagate or
442
+modify any covered work.  These actions infringe copyright if you do
443
+not accept this License.  Therefore, by modifying or propagating a
444
+covered work, you indicate your acceptance of this License to do so.
445
+
446
+  10. Automatic Licensing of Downstream Recipients.
447
+
448
+  Each time you convey a covered work, the recipient automatically
449
+receives a license from the original licensors, to run, modify and
450
+propagate that work, subject to this License.  You are not responsible
451
+for enforcing compliance by third parties with this License.
452
+
453
+  An "entity transaction" is a transaction transferring control of an
454
+organization, or substantially all assets of one, or subdividing an
455
+organization, or merging organizations.  If propagation of a covered
456
+work results from an entity transaction, each party to that
457
+transaction who receives a copy of the work also receives whatever
458
+licenses to the work the party's predecessor in interest had or could
459
+give under the previous paragraph, plus a right to possession of the
460
+Corresponding Source of the work from the predecessor in interest, if
461
+the predecessor has it or can get it with reasonable efforts.
462
+
463
+  You may not impose any further restrictions on the exercise of the
464
+rights granted or affirmed under this License.  For example, you may
465
+not impose a license fee, royalty, or other charge for exercise of
466
+rights granted under this License, and you may not initiate litigation
467
+(including a cross-claim or counterclaim in a lawsuit) alleging that
468
+any patent claim is infringed by making, using, selling, offering for
469
+sale, or importing the Program or any portion of it.
470
+
471
+  11. Patents.
472
+
473
+  A "contributor" is a copyright holder who authorizes use under this
474
+License of the Program or a work on which the Program is based.  The
475
+work thus licensed is called the contributor's "contributor version".
476
+
477
+  A contributor's "essential patent claims" are all patent claims
478
+owned or controlled by the contributor, whether already acquired or
479
+hereafter acquired, that would be infringed by some manner, permitted
480
+by this License, of making, using, or selling its contributor version,
481
+but do not include claims that would be infringed only as a
482
+consequence of further modification of the contributor version.  For
483
+purposes of this definition, "control" includes the right to grant
484
+patent sublicenses in a manner consistent with the requirements of
485
+this License.
486
+
487
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
488
+patent license under the contributor's essential patent claims, to
489
+make, use, sell, offer for sale, import and otherwise run, modify and
490
+propagate the contents of its contributor version.
491
+
492
+  In the following three paragraphs, a "patent license" is any express
493
+agreement or commitment, however denominated, not to enforce a patent
494
+(such as an express permission to practice a patent or covenant not to
495
+sue for patent infringement).  To "grant" such a patent license to a
496
+party means to make such an agreement or commitment not to enforce a
497
+patent against the party.
498
+
499
+  If you convey a covered work, knowingly relying on a patent license,
500
+and the Corresponding Source of the work is not available for anyone
501
+to copy, free of charge and under the terms of this License, through a
502
+publicly available network server or other readily accessible means,
503
+then you must either (1) cause the Corresponding Source to be so
504
+available, or (2) arrange to deprive yourself of the benefit of the
505
+patent license for this particular work, or (3) arrange, in a manner
506
+consistent with the requirements of this License, to extend the patent
507
+license to downstream recipients.  "Knowingly relying" means you have
508
+actual knowledge that, but for the patent license, your conveying the
509
+covered work in a country, or your recipient's use of the covered work
510
+in a country, would infringe one or more identifiable patents in that
511
+country that you have reason to believe are valid.
512
+
513
+  If, pursuant to or in connection with a single transaction or
514
+arrangement, you convey, or propagate by procuring conveyance of, a
515
+covered work, and grant a patent license to some of the parties
516
+receiving the covered work authorizing them to use, propagate, modify
517
+or convey a specific copy of the covered work, then the patent license
518
+you grant is automatically extended to all recipients of the covered
519
+work and works based on it.
520
+
521
+  A patent license is "discriminatory" if it does not include within
522
+the scope of its coverage, prohibits the exercise of, or is
523
+conditioned on the non-exercise of one or more of the rights that are
524
+specifically granted under this License.  You may not convey a covered
525
+work if you are a party to an arrangement with a third party that is
526
+in the business of distributing software, under which you make payment
527
+to the third party based on the extent of your activity of conveying
528
+the work, and under which the third party grants, to any of the
529
+parties who would receive the covered work from you, a discriminatory
530
+patent license (a) in connection with copies of the covered work
531
+conveyed by you (or copies made from those copies), or (b) primarily
532
+for and in connection with specific products or compilations that
533
+contain the covered work, unless you entered into that arrangement,
534
+or that patent license was granted, prior to 28 March 2007.
535
+
536
+  Nothing in this License shall be construed as excluding or limiting
537
+any implied license or other defenses to infringement that may
538
+otherwise be available to you under applicable patent law.
539
+
540
+  12. No Surrender of Others' Freedom.
541
+
542
+  If conditions are imposed on you (whether by court order, agreement or
543
+otherwise) that contradict the conditions of this License, they do not
544
+excuse you from the conditions of this License.  If you cannot convey a
545
+covered work so as to satisfy simultaneously your obligations under this
546
+License and any other pertinent obligations, then as a consequence you may
547
+not convey it at all.  For example, if you agree to terms that obligate you
548
+to collect a royalty for further conveying from those to whom you convey
549
+the Program, the only way you could satisfy both those terms and this
550
+License would be to refrain entirely from conveying the Program.
551
+
552
+  13. Use with the GNU Affero General Public License.
553
+
554
+  Notwithstanding any other provision of this License, you have
555
+permission to link or combine any covered work with a work licensed
556
+under version 3 of the GNU Affero General Public License into a single
557
+combined work, and to convey the resulting work.  The terms of this
558
+License will continue to apply to the part which is the covered work,
559
+but the special requirements of the GNU Affero General Public License,
560
+section 13, concerning interaction through a network will apply to the
561
+combination as such.
562
+
563
+  14. Revised Versions of this License.
564
+
565
+  The Free Software Foundation may publish revised and/or new versions of
566
+the GNU General Public License from time to time.  Such new versions will
567
+be similar in spirit to the present version, but may differ in detail to
568
+address new problems or concerns.
569
+
570
+  Each version is given a distinguishing version number.  If the
571
+Program specifies that a certain numbered version of the GNU General
572
+Public License "or any later version" applies to it, you have the
573
+option of following the terms and conditions either of that numbered
574
+version or of any later version published by the Free Software
575
+Foundation.  If the Program does not specify a version number of the
576
+GNU General Public License, you may choose any version ever published
577
+by the Free Software Foundation.
578
+
579
+  If the Program specifies that a proxy can decide which future
580
+versions of the GNU General Public License can be used, that proxy's
581
+public statement of acceptance of a version permanently authorizes you
582
+to choose that version for the Program.
583
+
584
+  Later license versions may give you additional or different
585
+permissions.  However, no additional obligations are imposed on any
586
+author or copyright holder as a result of your choosing to follow a
587
+later version.
588
+
589
+  15. Disclaimer of Warranty.
590
+
591
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
+
600
+  16. Limitation of Liability.
601
+
602
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610
+SUCH DAMAGES.
611
+
612
+  17. Interpretation of Sections 15 and 16.
613
+
614
+  If the disclaimer of warranty and limitation of liability provided
615
+above cannot be given local legal effect according to their terms,
616
+reviewing courts shall apply local law that most closely approximates
617
+an absolute waiver of all civil liability in connection with the
618
+Program, unless a warranty or assumption of liability accompanies a
619
+copy of the Program in return for a fee.
620
+
621
+                     END OF TERMS AND CONDITIONS
622
+
623
+            How to Apply These Terms to Your New Programs
624
+
625
+  If you develop a new program, and you want it to be of the greatest
626
+possible use to the public, the best way to achieve this is to make it
627
+free software which everyone can redistribute and change under these terms.
628
+
629
+  To do so, attach the following notices to the program.  It is safest
630
+to attach them to the start of each source file to most effectively
631
+state the exclusion of warranty; and each file should have at least
632
+the "copyright" line and a pointer to where the full notice is found.
633
+
634
+    <one line to give the program's name and a brief idea of what it does.>
635
+    Copyright (C) <year>  <name of author>
636
+
637
+    This program is free software: you can redistribute it and/or modify
638
+    it under the terms of the GNU General Public License as published by
639
+    the Free Software Foundation, either version 3 of the License, or
640
+    (at your option) any later version.
641
+
642
+    This program is distributed in the hope that it will be useful,
643
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
644
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
645
+    GNU General Public License for more details.
646
+
647
+    You should have received a copy of the GNU General Public License
648
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
649
+
650
+Also add information on how to contact you by electronic and paper mail.
651
+
652
+  If the program does terminal interaction, make it output a short
653
+notice like this when it starts in an interactive mode:
654
+
655
+    <program>  Copyright (C) <year>  <name of author>
656
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
+    This is free software, and you are welcome to redistribute it
658
+    under certain conditions; type `show c' for details.
659
+
660
+The hypothetical commands `show w' and `show c' should show the appropriate
661
+parts of the General Public License.  Of course, your program's commands
662
+might be different; for a GUI interface, you would use an "about box".
663
+
664
+  You should also get your employer (if you work as a programmer) or school,
665
+if any, to sign a "copyright disclaimer" for the program, if necessary.
666
+For more information on this, and how to apply and follow the GNU GPL, see
667
+<http://www.gnu.org/licenses/>.
668
+
669
+  The GNU General Public License does not permit incorporating your program
670
+into proprietary programs.  If your program is a subroutine library, you
671
+may consider it more useful to permit linking proprietary applications with
672
+the library.  If this is what you want to do, use the GNU Lesser General
673
+Public License instead of this License.  But first, please read
674
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.

+ 28
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/README.md View File

@@ -0,0 +1,28 @@
1
+FTDI EVE Library
2
+----------------
3
+
4
+The FTDI EVE Library is a fully open-source library and UI framework for the FTDI
5
+FT800 and FT810 graphics processor.
6
+
7
+Although the library has been developed within Lulzbot for providing a user interface
8
+for Marlin, the library has been written so that it can be used in any Arduino sketch.
9
+
10
+The library is split into two parts. The "basic" API provides a shallow interface to
11
+the underlying FTDI hardware and command FIFO and provides low-level access to the
12
+hardware as closely as possible to the API described in the FTDI Programmer's Guide.
13
+
14
+The "extended" API builds on top of the "basic" API to provide a GUI framework for
15
+handling common challenges in building a usable GUI. The GUI framework provides the
16
+following features:
17
+
18
+- Macros for a resolution-independent placement of widgets based on a grid.
19
+- Class-based UI screens, with press and unpress touch events, as well as touch repeat.
20
+- Event loop with button debouncing and button push visual and auditory feedback.
21
+- Easy screen-to-screen navigation including a navigation stack for going backwards.
22
+- Visual feedback for disabled vs enabled buttons, and custom button styles.
23
+- A sound player class for playing individual notes or complete sound sequences.
24
+- Display list caching, for storing static background elements of a screen in RAM_G.
25
+
26
+See the "examples" folder for Arduino sketches. Modify the "src/config.h" file in
27
+each to suit your particular setup. The "sample_configs" contain sample configuration
28
+files for running the sketches on our 3D printer boards.

+ 183
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/boards.h View File

@@ -0,0 +1,183 @@
1
+/************
2
+ * boards.h *
3
+ ************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+#define HAS_RESOLUTION (defined(TOUCH_UI_320x240) || defined(TOUCH_UI_480x272) || defined(TOUCH_UI_800x480))
26
+
27
+#define IS_FT800 \
28
+    constexpr uint16_t ftdi_chip = 800; \
29
+    using namespace FTDI_FT800; \
30
+    namespace DL { \
31
+      using namespace FTDI_FT800_DL; \
32
+    } \
33
+    typedef ft800_memory_map ftdi_memory_map; \
34
+    typedef ft800_registers  ftdi_registers;
35
+
36
+#define IS_FT810 \
37
+    constexpr uint16_t ftdi_chip = 810; \
38
+    using namespace FTDI_FT810; \
39
+    namespace DL { \
40
+      using namespace FTDI_FT800_DL; \
41
+      using namespace FTDI_FT810_DL; \
42
+    } \
43
+    typedef ft810_memory_map ftdi_memory_map; \
44
+    typedef ft810_registers  ftdi_registers;
45
+
46
+
47
+#ifdef LCD_FTDI_VM800B35A
48
+  #if !HAS_RESOLUTION
49
+    #define TOUCH_UI_320x240
50
+  #endif
51
+  #ifndef FTDI_API_LEVEL
52
+    #define FTDI_API_LEVEL                800
53
+  #endif
54
+  namespace FTDI {
55
+    IS_FT800
56
+    constexpr bool Use_Crystal              = true;  // 0 = use internal oscillator, 1 = module has a crystal populated
57
+    constexpr bool GPIO_0_Audio_Enable      = false; /* 1 = does use GPIO00 for amplifier control, 0 = not in use for Audio */
58
+    constexpr bool GPIO_1_Audio_Shutdown    = true;  /* 1 = does use GPIO01 for amplifier control, 0 = not in use for Audio */
59
+    constexpr uint8_t Swizzle               = 2;
60
+    constexpr uint8_t CSpread               = 1;
61
+
62
+    constexpr uint16_t touch_threshold      = 1200; /* touch-sensitivity */
63
+  }
64
+
65
+/*
66
+ * Settings for the Haoyu Electronics, 4.3" Graphical LCD Touchscreen,       480x272, SPI, FT800 (FT800CB-HY43B)
67
+ *                  Haoyu Electronics,   5" Graphical LCD Touchscreen,       480x272, SPI, FT800 (FT800CB-HY50B)
68
+ *
69
+ *    http://www.hotmcu.com/43-graphical-lcd-touchscreen-480x272-spi-ft800-p-111.html?cPath=6_16
70
+ *    http://www.hotmcu.com/5-graphical-lcd-touchscreen-480x272-spi-ft800-p-124.html?cPath=6_16
71
+ *
72
+ * Datasheet:
73
+ *
74
+ *    http://www.hantronix.com/files/data/1278363262430-3.pdf
75
+ *    http://www.haoyuelectronics.com/Attachment/HY43-LCD/LCD%20DataSheet.pdf
76
+ *    http://www.haoyuelectronics.com/Attachment/HY5-LCD-HD/KD50G21-40NT-A1.pdf
77
+ *
78
+ */
79
+
80
+#elif defined(LCD_HAOYU_FT800CB)
81
+  #if !HAS_RESOLUTION
82
+    #define TOUCH_UI_480x272
83
+  #endif
84
+  #ifndef FTDI_API_LEVEL
85
+    #define FTDI_API_LEVEL                800
86
+  #endif
87
+  namespace FTDI {
88
+    IS_FT800
89
+    constexpr bool Use_Crystal              = true; // 0 = use internal oscillator, 1 = module has a crystal populated
90
+    constexpr bool GPIO_0_Audio_Enable      = false;
91
+    constexpr bool GPIO_1_Audio_Shutdown    = false;
92
+    constexpr uint8_t Swizzle               = 0;
93
+    constexpr uint8_t CSpread               = 1;
94
+    constexpr uint16_t touch_threshold      = 2000; /* touch-sensitivity */
95
+  }
96
+
97
+/*
98
+ * Settings for the Haoyu Electronics, 5" Graphical LCD Touchscreen, 800x480, SPI, FT810
99
+ *
100
+ *    http://www.hotmcu.com/5-graphical-lcd-touchscreen-800x480-spi-ft810-p-286.html
101
+ *
102
+ * Datasheet:
103
+ *
104
+ *    http://www.haoyuelectronics.com/Attachment/HY5-LCD-HD/KD50G21-40NT-A1.pdf
105
+ *
106
+ */
107
+
108
+#elif defined(LCD_HAOYU_FT810CB)
109
+  #if !HAS_RESOLUTION
110
+    #define TOUCH_UI_800x480
111
+  #endif
112
+  #ifndef FTDI_API_LEVEL
113
+    #define FTDI_API_LEVEL                810
114
+  #endif
115
+  namespace FTDI {
116
+    IS_FT810
117
+    constexpr bool Use_Crystal              = true; // 0 = use internal oscillator, 1 = module has a crystal populated
118
+    constexpr bool GPIO_0_Audio_Enable      = false;
119
+    constexpr bool GPIO_1_Audio_Shutdown    = false;
120
+    constexpr uint8_t Swizzle               = 0;
121
+    constexpr uint8_t CSpread               = 1;
122
+    constexpr uint16_t touch_threshold      = 2000; /* touch-sensitivity */
123
+  }
124
+
125
+/*
126
+ * Settings for the 4D Systems,        4.3" Embedded SPI Display             480x272, SPI, FT800 (4DLCD-FT843)
127
+ *
128
+ *    http://www.4dsystems.com.au/product/4DLCD_FT843/
129
+ *
130
+ * Datasheet:
131
+ *
132
+ *    http://www.4dsystems.com.au/productpages/4DLCD-FT843/downloads/FT843-4.3-Display_datasheet_R_1_2.pdf
133
+ *
134
+ */
135
+
136
+#elif defined(LCD_4DSYSTEMS_4DLCD_FT843)
137
+  #if !HAS_RESOLUTION
138
+    #define TOUCH_UI_480x272
139
+  #endif
140
+  #ifndef FTDI_API_LEVEL
141
+    #define FTDI_API_LEVEL                800
142
+  #endif
143
+  namespace FTDI {
144
+    IS_FT800
145
+    constexpr bool Use_Crystal              = true; // 0 = use internal oscillator, 1 = module has a crystal populated
146
+    constexpr bool GPIO_0_Audio_Enable      = false;
147
+    constexpr bool GPIO_1_Audio_Shutdown    = true;
148
+    constexpr uint8_t Swizzle               = 0;
149
+    constexpr uint8_t CSpread               = 1;
150
+    constexpr uint16_t touch_threshold      = 1200; /* touch-sensitivity */
151
+  }
152
+
153
+/*
154
+ * Settings for the Aleph Objects Color LCD User Interface
155
+ *
156
+ *    https://code.alephobjects.com/source/aotctl/
157
+ *
158
+ * Datasheet:
159
+ *
160
+ *    http://www.hantronix.com/files/data/s1501799605s500-gh7.pdf
161
+ *
162
+ */
163
+#elif defined(LCD_ALEPHOBJECTS_CLCD_UI)
164
+  #if !HAS_RESOLUTION
165
+    #define TOUCH_UI_800x480
166
+  #endif
167
+  #ifndef FTDI_API_LEVEL
168
+    #define FTDI_API_LEVEL                810
169
+  #endif
170
+  namespace FTDI {
171
+    IS_FT810
172
+    constexpr bool Use_Crystal              = false; // 0 = use internal oscillator, 1 = module has a crystal populated
173
+    constexpr bool GPIO_0_Audio_Enable      = true;  // The AO CLCD uses GPIO0 to enable audio
174
+    constexpr bool GPIO_1_Audio_Shutdown    = false;
175
+    constexpr uint8_t Swizzle               = 0;
176
+    constexpr uint8_t CSpread               = 0;
177
+    constexpr uint16_t touch_threshold      = 2000; /* touch-sensitivity */
178
+  }
179
+
180
+#else
181
+
182
+  #error Unknown or no LULZBOT_TOUCH_UI board specified. To add a new board, modify "ftdi_eve_boards.h"
183
+#endif

+ 1174
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.cpp
File diff suppressed because it is too large
View File


+ 258
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.h View File

@@ -0,0 +1,258 @@
1
+/****************
2
+ * commands.cpp *
3
+ ****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+  /****************************************************************************
24
+  *                       FUNCTION MAP                                        *
25
+  *                                                                           *
26
+  * SPI and FT800/810 Commands                                                *
27
+  *                                                                           *
28
+  * CLCD::spi_select()                 Set CS line to 0                       *
29
+  * CLCD::spi_deselect()               Set CS Line to 1                       *
30
+  * CLCD::reset()                      Toggle FT800/810 Power Down Line 50 ms *
31
+  * CLCD::spi_init()                   Configure I/O Lines for SPI            *
32
+  * CLCD::spi_transfer()               Send/Receive 1 SPI Byte                *
33
+  * CLCD::init()                       Set FT800/810 Registers                *
34
+  * CLCD::enable()                     Turn On FT800/810 PCLK                 *
35
+  * CLCD::disable()                    Turn Off FT8880/810 PCLK               *
36
+  * CLCD::set_backlight()              Set LCD Backlight Level                *
37
+  *                                                                           *
38
+  * MEMORY READ FUNCTIONS                                                     *
39
+  *                                                                           *
40
+  * CLCD::mem_read_addr()              Send 32-Bit Address                    *
41
+  * CLCD::mem_read_8()                 Read 1 Byte                            *
42
+  * CLCD::mem_read_16()                Read 2 Bytes                           *
43
+  * CLCD::mem_read_32()                Read 4 Bytes                           *
44
+  *                                                                           *
45
+  * MEMORY WRITE FUNCTIONS                                                    *
46
+  *                                                                           *
47
+  * CLCD::mem_write_addr()             Send 24-Bit Address                    *
48
+  * CLCD::mem_write_8()                Write 1 Byte                           *
49
+  * CLCD::mem_write_16()               Write 2 Bytes                          *
50
+  * CLCD::mem_write_32()               Write 4 Bytes                          *
51
+  *                                                                           *
52
+  * HOST COMMAND FUNCTION                                                     *
53
+  *                                                                           *
54
+  * CLCD::host_cmd()                   Send 24-Bit Host Command               *
55
+  *                                                                           *
56
+  * COMMAND BUFFER FUNCTIONS                                                  *
57
+  *                                                                           *
58
+  * CLCD::cmd()                        Send 32-Bit Value(4 Bytes)CMD Buffer   *
59
+  * CLCD::cmd()                        Send Data Structure with 32-Bit Cmd    *
60
+  * CLCD::str()                        Send Text String in 32-Bit Multiples   *
61
+
62
+  *                                                                           *
63
+  * FT800/810 GRAPHIC COMMANDS                                                *
64
+  *                                                                           *
65
+  * class CLCD:CommandFifo {}          Class to control Cmd FIFO              *
66
+
67
+  * CommandFifo::start()               Wait for CP finish - Set FIFO Ptr      *
68
+  * CommandFifo::execute()             Set REG_CMD_WRITE and start CP         *
69
+  * CommandFifo::reset()               Set Cmd Buffer Pointers to 0           *
70
+  *
71
+  * CommandFifo::fgcolor               Set Graphic Item Foreground Color      *
72
+  * CommandFifo::bgcolor               Set Graphic Item Background Color      *
73
+  * CommandFifo::begin()               Begin Drawing a Primative              *
74
+  * CommandFifo::mem_copy()            Copy a Block of Memory                 *
75
+  * CommandFifo::append()              Append Commands to Current DL          *
76
+  * CommandFifo::gradient_color()      Set 3D Button Highlight Color          *
77
+  * CommandFifo::button()              Draw Button with Bulk Write            *
78
+  * CommandFifo::text()                Draw Text with Bulk Write              *
79
+  *****************************************************************************/
80
+
81
+ /**************************************************
82
+  * RAM_G Graphics RAM Allocation                  *
83
+  *                                                *
84
+  * Address    Use                                 *
85
+  *                                                *
86
+  *    8000    Extruder Bitmap                     *
87
+  *    8100    Bed Heat Bitmap                     *
88
+  *    8200    Fan Bitmap                          *
89
+  *    8300    Thumb Drive Symbol Bitmap           *
90
+  *   35000    Static DL Space (FT800)             *
91
+  *   F5000    Static DL Space (FT810)             *
92
+  **************************************************/
93
+
94
+#pragma once
95
+
96
+typedef const __FlashStringHelper *progmem_str;
97
+
98
+class UIStorage;
99
+
100
+class CLCD {
101
+  friend class UIStorage;
102
+
103
+  public:
104
+    typedef FTDI::ftdi_registers  REG;
105
+    typedef FTDI::ftdi_memory_map MAP;
106
+
107
+    static void     spi_write_addr (uint32_t reg_address);
108
+    static void     spi_read_addr  (uint32_t reg_address);
109
+
110
+    static uint8_t  mem_read_8     (uint32_t reg_address);
111
+    static uint16_t mem_read_16    (uint32_t reg_address);
112
+    static uint32_t mem_read_32    (uint32_t reg_address);
113
+    static void     mem_read_bulk  (uint32_t reg_address, uint8_t *data, uint16_t len);
114
+
115
+    static void     mem_write_8    (uint32_t reg_address, uint8_t w_data);
116
+    static void     mem_write_16   (uint32_t reg_address, uint16_t w_data);
117
+    static void     mem_write_32   (uint32_t reg_address, uint32_t w_data);
118
+    static void     mem_write_bulk (uint32_t reg_address, const void *data, uint16_t len, uint8_t padding = 0);
119
+    static void     mem_write_pgm  (uint32_t reg_address, const void *data, uint16_t len, uint8_t padding = 0);
120
+    static void     mem_write_bulk (uint32_t reg_address, progmem_str str, uint16_t len, uint8_t padding = 0);
121
+    static void     mem_write_xbm  (uint32_t reg_address, progmem_str str, uint16_t len, uint8_t padding = 0);
122
+
123
+  public:
124
+    class CommandFifo;
125
+    class FontMetrics;
126
+
127
+    static void init (void);
128
+    static void default_touch_transform (void);
129
+    static void default_display_orientation (void);
130
+    static void turn_on_backlight (void);
131
+    static void enable (void);
132
+    static void disable (void);
133
+    static void set_brightness (uint8_t brightness);
134
+    static uint8_t get_brightness();
135
+    static void host_cmd (unsigned char host_command, unsigned char byte2);
136
+
137
+    static void get_font_metrics (uint8_t font, struct FontMetrics &fm);
138
+    static uint16_t get_text_width(const uint8_t font, const char *str);
139
+    static uint16_t get_text_width_P(const uint8_t font, const char *str);
140
+
141
+    static uint8_t get_tag ()     {return mem_read_8(REG::TOUCH_TAG);}
142
+    static bool is_touching ()    {return (mem_read_32(REG::TOUCH_DIRECT_XY) & 0x80000000) == 0;}
143
+
144
+    static uint8_t get_tracker (uint16_t &value) {
145
+      uint32_t tracker = mem_read_32(REG::TRACKER);
146
+      value            = tracker >> 16;
147
+      return tracker & 0xFF;
148
+    }
149
+};
150
+
151
+/*************************** FT800/810 Font Metrics ****************************/
152
+
153
+class CLCD::FontMetrics {
154
+  public:
155
+    uint8_t   char_widths[128];
156
+    uint32_t  format;
157
+    uint32_t  stride;
158
+    uint32_t  width;
159
+    uint32_t  height;
160
+    uint32_t  ptr;
161
+
162
+    FontMetrics(uint8_t font) {load(font);}
163
+
164
+    void load(uint8_t font);
165
+
166
+    // Returns width of string, up to a maximum of n characters.
167
+    uint16_t get_text_width(const char *str, size_t n = SIZE_MAX) const;
168
+    uint16_t get_text_width_P(const char *str, size_t n = SIZE_MAX) const;
169
+};
170
+
171
+/******************* FT800/810 Graphic Commands *********************************/
172
+
173
+class CLCD::CommandFifo {
174
+  protected:
175
+    #if FTDI_API_LEVEL >= 810
176
+      uint32_t getRegCmdBSpace();
177
+    #else
178
+      static uint32_t command_write_ptr;
179
+      template <class T> bool _write_unaligned(T data, uint16_t len);
180
+    #endif
181
+    void start(void);
182
+
183
+  public:
184
+    template <class T> bool write(T data, uint16_t len);
185
+
186
+  public:
187
+    CommandFifo() {start();}
188
+
189
+    static void reset (void);
190
+    static bool is_processing();
191
+    static bool has_fault();
192
+
193
+    void execute(void);
194
+
195
+    void cmd(uint32_t cmd32);
196
+    void cmd(void* data, uint16_t len);
197
+
198
+    void dlstart()      {cmd(FTDI::CMD_DLSTART);}
199
+    void swap()         {cmd(FTDI::CMD_SWAP);}
200
+    void coldstart()    {cmd(FTDI::CMD_COLDSTART);}
201
+    void screensaver()  {cmd(FTDI::CMD_SCREENSAVER);}
202
+    void stop()         {cmd(FTDI::CMD_STOP);}
203
+    void loadidentity() {cmd(FTDI::CMD_LOADIDENTITY);}
204
+    void setmatrix()    {cmd(FTDI::CMD_SETMATRIX);}
205
+
206
+    void fgcolor     (uint32_t rgb);
207
+    void bgcolor     (uint32_t rgb);
208
+    void gradcolor   (uint32_t rgb);
209
+
210
+    void track       (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t tag);
211
+    void clock       (int16_t x, int16_t y, int16_t r,            uint16_t options, int16_t h, int16_t m, int16_t s, int16_t ms);
212
+    void gauge       (int16_t x, int16_t y, int16_t r,            uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range);
213
+    void dial        (int16_t x, int16_t y, int16_t r,            uint16_t options, uint16_t val);
214
+    void slider      (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
215
+    void progress    (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
216
+    void scrollbar   (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t size, uint16_t range);
217
+    void number      (int16_t x, int16_t y, int16_t font, uint16_t options, int32_t n);
218
+    void spinner     (int16_t x, int16_t y, uint16_t style, uint16_t scale);
219
+    void sketch      (int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format);
220
+    void gradient    (int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1);
221
+    void snapshot    (uint32_t ptr);
222
+    void loadimage   (uint32_t ptr, uint32_t options);
223
+    void getprops    (uint32_t ptr, uint32_t width, uint32_t height);
224
+
225
+    void scale       (int32_t sx, int32_t sy);
226
+    void rotate      (int32_t a);
227
+    void translate   (int32_t tx, int32_t ty);
228
+
229
+    #if FTDI_API_LEVEL >= 810
230
+      void setbase   (uint8_t base);
231
+      void setrotate (uint8_t rotation);
232
+      void setbitmap (uint32_t ptr, uint16_t fmt, uint16_t w, uint16_t h);
233
+      void snapshot2 (uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, uint16_t w, uint16_t h);
234
+      void mediafifo (uint32_t ptr, uint32_t size);
235
+      void playvideo (uint32_t options);
236
+      void videostart();
237
+      void videoframe(uint32_t dst, uint32_t ptr);
238
+    #endif
239
+
240
+    // All the following must be followed by str()
241
+    void text      (int16_t x, int16_t y,                       int16_t font, uint16_t options);
242
+    void button    (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t option);
243
+    void toggle    (int16_t x, int16_t y, int16_t w,            int16_t font, uint16_t options, bool state);
244
+    void keys      (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options);
245
+
246
+    // Sends the string portion of text, button, toggle and keys.
247
+    void str (const char * data);
248
+    void str (progmem_str data);
249
+
250
+    void memzero  (uint32_t ptr, uint32_t size);
251
+    void memset   (uint32_t ptr, uint32_t value, uint32_t size);
252
+    void memcpy   (uint32_t dst, uint32_t src, uint32_t size);
253
+    void memcrc   (uint32_t ptr, uint32_t num, uint32_t result);
254
+    void memwrite (uint32_t ptr, uint32_t value);
255
+    void inflate  (uint32_t ptr);
256
+    void getptr   (uint32_t result);
257
+    void append   (uint32_t ptr, uint32_t size);
258
+};

+ 411
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/constants.h View File

@@ -0,0 +1,411 @@
1
+/***************
2
+ * constants.h *
3
+ ***************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+/****************************************************************************
24
+ * This header defines constants and commands for the FTDI FT810 LCD Driver *
25
+ * chip.                                                                    *
26
+ ****************************************************************************/
27
+
28
+#pragma once
29
+
30
+// OPTIONS
31
+
32
+namespace FTDI {
33
+  constexpr uint16_t OPT_3D           = 0x0000;
34
+  constexpr uint16_t OPT_RGB565       = 0x0000;
35
+  constexpr uint16_t OPT_MONO         = 0x0001;
36
+  constexpr uint16_t OPT_NODL         = 0x0002;
37
+  constexpr uint16_t OPT_FLAT         = 0x0100;
38
+  constexpr uint16_t OPT_SIGNED       = 0x0100;
39
+  constexpr uint16_t OPT_CENTERX      = 0x0200;
40
+  constexpr uint16_t OPT_CENTERY      = 0x0400;
41
+  constexpr uint16_t OPT_CENTER       = (OPT_CENTERX | OPT_CENTERY);
42
+  constexpr uint16_t OPT_RIGHTX       = 0x0800;
43
+  constexpr uint16_t OPT_NOBACK       = 0x1000;
44
+  constexpr uint16_t OPT_NOTICKS      = 0x2000;
45
+  constexpr uint16_t OPT_NOHM         = 0x4000;
46
+  constexpr uint16_t OPT_NOPOINTER    = 0x4000;
47
+  constexpr uint16_t OPT_NOSECS       = 0x8000;
48
+  constexpr uint16_t OPT_NOHANDS      = (OPT_NOPOINTER | OPT_NOSECS);
49
+}
50
+
51
+namespace FTDI_FT810 {
52
+  constexpr uint16_t OPT_NOTEAR      = 0x0004;
53
+  constexpr uint16_t OPT_FULLSCREEN  = 0x0008;
54
+  constexpr uint16_t OPT_MEDIAFIFO   = 0x0010;
55
+  constexpr uint16_t OPT_SOUND       = 0x0020;
56
+}
57
+
58
+// GPIO Bits
59
+
60
+namespace FTDI {
61
+  constexpr uint8_t GPIO_GP0         = 1 << 0;
62
+  constexpr uint8_t GPIO_GP1         = 1 << 1;
63
+  constexpr uint8_t GPIO_DISP        = 1 << 7;
64
+}
65
+
66
+namespace FTDI_FT810 {
67
+  constexpr uint16_t GPIOX_GP0       = 1 << 0;
68
+  constexpr uint16_t GPIOX_GP1       = 1 << 1;
69
+  constexpr uint16_t GPIOX_DISP      = 1 << 15;
70
+}
71
+
72
+// HOST COMMANDS
73
+
74
+namespace FTDI {
75
+  constexpr uint8_t ACTIVE  = 0x00;
76
+  constexpr uint8_t STANDBY = 0x41;
77
+  constexpr uint8_t SLEEP   = 0x42;
78
+  constexpr uint8_t PWRDOWN = 0x50;
79
+  constexpr uint8_t CLKEXT  = 0x44;
80
+  constexpr uint8_t CLKINT  = 0x48;
81
+  constexpr uint8_t CORESET = 0x68;
82
+}
83
+
84
+namespace FTDI_FT800 {
85
+    constexpr uint8_t CLK48M  = 0x62;
86
+    constexpr uint8_t CLK36M  = 0x61;
87
+}
88
+
89
+namespace FTDI_FT810 {
90
+    constexpr uint8_t CLKSEL  = 0x61;
91
+}
92
+
93
+// DISPLAY LIST COMMANDS
94
+
95
+namespace FTDI {
96
+  constexpr uint8_t ARGB1555                           = 0;
97
+  constexpr uint8_t L1                                 = 1;
98
+  constexpr uint8_t L4                                 = 2;
99
+  constexpr uint8_t L8                                 = 3;
100
+  constexpr uint8_t RGB332                             = 4;
101
+  constexpr uint8_t ARGB2                              = 5;
102
+  constexpr uint8_t ARGB4                              = 6;
103
+  constexpr uint8_t RGB565                             = 7;
104
+  constexpr uint8_t PALETTED                           = 8;
105
+  constexpr uint8_t TEXT8X8                            = 9;
106
+  constexpr uint8_t TEXTVGA                            = 10;
107
+  constexpr uint8_t BARGRAPH                           = 11;
108
+
109
+  constexpr uint8_t ALPHA_FUNC_NEVER                   = 0;
110
+  constexpr uint8_t ALPHA_FUNC_LESS                    = 1;
111
+  constexpr uint8_t ALPHA_FUNC_LEQUAL                  = 2;
112
+  constexpr uint8_t ALPHA_FUNC_GREATER                 = 3;
113
+  constexpr uint8_t ALPHA_FUNC_GEQUAL                  = 4;
114
+  constexpr uint8_t ALPHA_FUNC_EQUAL                   = 5;
115
+  constexpr uint8_t ALPHA_FUNC_NOTEQUAL                = 6;
116
+  constexpr uint8_t ALPHA_FUNC_ALWAYS                  = 7;
117
+
118
+  constexpr uint8_t NEAREST                            = 0;
119
+  constexpr uint8_t BILINEAR                           = 1;
120
+  constexpr uint8_t BORDER                             = 0;
121
+  constexpr uint8_t REPEAT                             = 1;
122
+
123
+  constexpr uint8_t BLEND_FUNC_ZERO                    = 0;
124
+  constexpr uint8_t BLEND_FUNC_ONE                     = 1;
125
+  constexpr uint8_t BLEND_FUNC_SRC_ALPHA               = 2;
126
+  constexpr uint8_t BLEND_FUNC_DST_ALPHA               = 3;
127
+  constexpr uint8_t BLEND_FUNC_ONE_MINUS_SRC_ALPHA     = 4;
128
+  constexpr uint8_t BLEND_FUNC_ONE_MINUS_DST_ALPHA     = 5;
129
+
130
+  constexpr uint32_t COLOR_MASK_RED                    = 8;
131
+  constexpr uint32_t COLOR_MASK_GRN                    = 4;
132
+  constexpr uint32_t COLOR_MASK_BLU                    = 2;
133
+  constexpr uint32_t COLOR_MASK_ALPHA                  = 1;
134
+
135
+  constexpr uint8_t STENCIL_FUNC_NEVER                 = 0;
136
+  constexpr uint8_t STENCIL_FUNC_LESS                  = 1;
137
+  constexpr uint8_t STENCIL_FUNC_LEQUAL                = 2;
138
+  constexpr uint8_t STENCIL_FUNC_GREATER               = 3;
139
+  constexpr uint8_t STENCIL_FUNC_GEQUAL                = 4;
140
+  constexpr uint8_t STENCIL_FUNC_EQUAL                 = 5;
141
+  constexpr uint8_t STENCIL_FUNC_NOTEQUAL              = 6;
142
+  constexpr uint8_t STENCIL_FUNC_ALWAYS                = 7;
143
+
144
+  constexpr uint8_t STENCIL_OP_ZERO                    = 0;
145
+  constexpr uint8_t STENCIL_OP_KEEP                    = 1;
146
+  constexpr uint8_t STENCIL_OP_REPLACE                 = 2;
147
+  constexpr uint8_t STENCIL_OP_INCR                    = 3;
148
+  constexpr uint8_t STENCIL_OP_DECR                    = 4;
149
+  constexpr uint8_t STENCIL_OP_INVERT                  = 5;
150
+
151
+  typedef enum: uint32_t {
152
+   BITMAPS                                             = 1,
153
+   POINTS                                              = 2,
154
+   LINES                                               = 3,
155
+   LINE_STRIP                                          = 4,
156
+   EDGE_STRIP_R                                        = 5,
157
+   EDGE_STRIP_L                                        = 6,
158
+   EDGE_STRIP_A                                        = 7,
159
+   EDGE_STRIP_B                                        = 8,
160
+   RECTS                                               = 9
161
+  } begin_t;
162
+}
163
+
164
+namespace FTDI_FT800_DL {
165
+  constexpr uint32_t ALPHA_FUNC                         = 0x09000000;
166
+  constexpr uint32_t BEGIN                              = 0x1F000000;
167
+  constexpr uint32_t BITMAP_HANDLE                      = 0x05000000;
168
+  constexpr uint32_t BITMAP_LAYOUT                      = 0x07000000;
169
+  constexpr uint32_t BITMAP_SIZE                        = 0x08000000;
170
+  constexpr uint32_t BITMAP_SOURCE                      = 0x01000000;
171
+  constexpr uint32_t BITMAP_TRANSFORM_A                 = 0x15000000;
172
+  constexpr uint32_t BITMAP_TRANSFORM_B                 = 0x16000000;
173
+  constexpr uint32_t BITMAP_TRANSFORM_C                 = 0x17000000;
174
+  constexpr uint32_t BITMAP_TRANSFORM_D                 = 0x18000000;
175
+  constexpr uint32_t BITMAP_TRANSFORM_E                 = 0x19000000;
176
+  constexpr uint32_t BITMAP_TRANSFORM_F                 = 0x1A000000;
177
+  constexpr uint32_t BLEND_FUNC                         = 0x0B000000;
178
+  constexpr uint32_t CALL                               = 0x1D000000;
179
+  constexpr uint32_t CELL                               = 0x06000000;
180
+  constexpr uint32_t CLEAR                              = 0x26000000;
181
+  constexpr uint32_t CLEAR_COLOR_BUFFER                 = 0x00000004;
182
+  constexpr uint32_t CLEAR_STENCIL_BUFFER               = 0x00000002;
183
+  constexpr uint32_t CLEAR_TAG_BUFFER                   = 0x00000001;
184
+  constexpr uint32_t CLEAR_COLOR_A                      = 0x0F000000;
185
+  constexpr uint32_t CLEAR_COLOR_RGB                    = 0x02000000;
186
+  constexpr uint32_t CLEAR_STENCIL                      = 0x11000000;
187
+  constexpr uint32_t CLEAR_TAG                          = 0x12000000;
188
+  constexpr uint32_t COLOR_A                            = 0x10000000;
189
+  constexpr uint32_t COLOR_MASK                         = 0x20000000;
190
+  constexpr uint32_t COLOR_RGB                          = 0x04000000;
191
+  constexpr uint32_t DL_DISPLAY                         = 0x00000000;
192
+  constexpr uint32_t END                                = 0x21000000;
193
+  constexpr uint32_t JUMP                               = 0x1E000000;
194
+  constexpr uint32_t LINE_WIDTH                         = 0x0E000000;
195
+  constexpr uint32_t MACRO                              = 0x25000000;
196
+  constexpr uint32_t POINT_SIZE                         = 0x0D000000;
197
+  constexpr uint32_t RESTORE_CONTEXT                    = 0x23000000;
198
+  constexpr uint32_t RETURN                             = 0x24000000;
199
+  constexpr uint32_t SAVE_CONTEXT                       = 0x22000000;
200
+  constexpr uint32_t SCISSOR_SIZE                       = 0x1C000000;
201
+  constexpr uint32_t SCISSOR_XY                         = 0x1B000000;
202
+  constexpr uint32_t STENCIL_FUNC                       = 0x0A000000;
203
+  constexpr uint32_t STENCIL_MASK                       = 0x13000000;
204
+  constexpr uint32_t STENCIL_OP                         = 0x0C000000;
205
+  constexpr uint32_t TAG                                = 0x03000000;
206
+  constexpr uint32_t TAG_MASK                           = 0x14000000;
207
+  constexpr uint32_t VERTEX2F                           = 0x40000000;
208
+  constexpr uint32_t VERTEX2II                          = 0x80000000;
209
+}
210
+
211
+namespace FTDI_FT810_DL {
212
+  constexpr uint32_t NOP                                = 0x25000000;
213
+  constexpr uint32_t BITMAP_LAYOUT_H                    = 0x28000000;
214
+  constexpr uint32_t BITMAP_SIZE_H                      = 0x29000000;
215
+  constexpr uint32_t VERTEX_FORMAT                      = 0x27000000;
216
+  constexpr uint32_t VERTEX_TRANSLATE_X                 = 0x2B000000;
217
+  constexpr uint32_t VERTEX_TRANSLATE_Y                 = 0x2C000000;
218
+}
219
+
220
+// CO-PROCESSOR ENGINE COMMANDS
221
+namespace FTDI {
222
+  constexpr uint32_t CMD_DLSTART                        = 0xFFFFFF00;
223
+  constexpr uint32_t CMD_SWAP                           = 0xFFFFFF01;
224
+  constexpr uint32_t CMD_COLDSTART                      = 0xFFFFFF32;
225
+  constexpr uint32_t CMD_INTERRUPT                      = 0xFFFFFF02;
226
+  constexpr uint32_t CMD_APPEND                         = 0xFFFFFF1E;
227
+  constexpr uint32_t CMD_REGREAD                        = 0xFFFFFF19;
228
+  constexpr uint32_t CMD_MEMWRITE                       = 0xFFFFFF1A;
229
+  constexpr uint32_t CMD_INFLATE                        = 0xFFFFFF22;
230
+  constexpr uint32_t CMD_LOADIMAGE                      = 0xFFFFFF24;
231
+  constexpr uint32_t CMD_MEMCRC                         = 0xFFFFFF18;
232
+  constexpr uint32_t CMD_MEMZERO                        = 0xFFFFFF1C;
233
+  constexpr uint32_t CMD_MEMSET                         = 0xFFFFFF1B;
234
+  constexpr uint32_t CMD_MEMCPY                         = 0xFFFFFF1D;
235
+  constexpr uint32_t CMD_BUTTON                         = 0xFFFFFF0D;
236
+  constexpr uint32_t CMD_CLOCK                          = 0xFFFFFF14;
237
+  constexpr uint32_t CMD_FGCOLOR                        = 0xFFFFFF0A;
238
+  constexpr uint32_t CMD_BGCOLOR                        = 0xFFFFFF09;
239
+  constexpr uint32_t CMD_GRADCOLOR                      = 0xFFFFFF34;
240
+  constexpr uint32_t CMD_GAUGE                          = 0xFFFFFF13;
241
+  constexpr uint32_t CMD_GRADIENT                       = 0xFFFFFF0B;
242
+  constexpr uint32_t CMD_KEYS                           = 0xFFFFFF0E;
243
+  constexpr uint32_t CMD_PROGRESS                       = 0xFFFFFF0F;
244
+  constexpr uint32_t CMD_SCROLLBAR                      = 0xFFFFFF11;
245
+  constexpr uint32_t CMD_SLIDER                         = 0xFFFFFF10;
246
+  constexpr uint32_t CMD_DIAL                           = 0xFFFFFF2D;
247
+  constexpr uint32_t CMD_TOGGLE                         = 0xFFFFFF12;
248
+  constexpr uint32_t CMD_TEXT                           = 0xFFFFFF0C;
249
+  constexpr uint32_t CMD_NUMBER                         = 0xFFFFFF2E;
250
+  constexpr uint32_t CMD_LOADIDENTITY                   = 0xFFFFFF26;
251
+  constexpr uint32_t CMD_SETMATRIX                      = 0xFFFFFF2A;
252
+  constexpr uint32_t CMD_GETMATRIX                      = 0xFFFFFF33;
253
+  constexpr uint32_t CMD_GETPTR                         = 0xFFFFFF23;
254
+  constexpr uint32_t CMD_GETPROPS                       = 0xFFFFFF25;
255
+  constexpr uint32_t CMD_SCALE                          = 0xFFFFFF28;
256
+  constexpr uint32_t CMD_ROTATE                         = 0xFFFFFF29;
257
+  constexpr uint32_t CMD_TRANSLATE                      = 0xFFFFFF27;
258
+  constexpr uint32_t CMD_CALIBRATE                      = 0xFFFFFF15;
259
+  constexpr uint32_t CMD_SPINNER                        = 0xFFFFFF16;
260
+  constexpr uint32_t CMD_SCREENSAVER                    = 0xFFFFFF2F;
261
+  constexpr uint32_t CMD_SKETCH                         = 0xFFFFFF30;
262
+  constexpr uint32_t CMD_STOP                           = 0xFFFFFF17;
263
+  constexpr uint32_t CMD_SETFONT                        = 0xFFFFFF2B;
264
+  constexpr uint32_t CMD_TRACK                          = 0xFFFFFF2C;
265
+  constexpr uint32_t CMD_SNAPSHOT                       = 0xFFFFFF1F;
266
+  constexpr uint32_t CMD_LOGO                           = 0xFFFFFF31;
267
+}
268
+
269
+namespace FTDI_FT810 {
270
+  constexpr uint32_t CMD_SETROTATE                    = 0xFFFFFF36;
271
+  constexpr uint32_t CMD_SNAPSHOT2                    = 0xFFFFFF37;
272
+  constexpr uint32_t CMD_SETBASE                      = 0xFFFFFF38;
273
+  constexpr uint32_t CMD_MEDIAFIFO                    = 0xFFFFFF39;
274
+  constexpr uint32_t CMD_PLAYVIDEO                    = 0xFFFFFF3A;
275
+  constexpr uint32_t CMD_VIDEOSTART                   = 0xFFFFFF40;
276
+  constexpr uint32_t CMD_VIDEOFRAME                   = 0xFFFFFF41;
277
+  constexpr uint32_t CMD_SETBITMAP                    = 0xFFFFFF43;
278
+}
279
+
280
+namespace FTDI {
281
+  enum effect_t {
282
+    SILENCE                                         = 0x00,
283
+    SQUARE_WAVE                                     = 0x01,
284
+    SINE_WAVE                                       = 0x02,
285
+    SAWTOOTH_WAVE                                   = 0x03,
286
+    TRIANGLE_WAVE                                   = 0x04,
287
+    BEEPING                                         = 0x05,
288
+    ALARM                                           = 0x06,
289
+    WARBLE                                          = 0x07,
290
+    CAROUSEL                                        = 0x08,
291
+    SHORT_PIPS_1                                    = 0x10,
292
+    SHORT_PIPS_2                                    = 0x11,
293
+    SHORT_PIPS_3                                    = 0x12,
294
+    SHORT_PIPS_4                                    = 0x13,
295
+    SHORT_PIPS_5                                    = 0x14,
296
+    SHORT_PIPS_6                                    = 0x15,
297
+    SHORT_PIPS_7                                    = 0x16,
298
+    SHORT_PIPS_8                                    = 0x17,
299
+    SHORT_PIPS_9                                    = 0x18,
300
+    SHORT_PIPS_10                                   = 0x19,
301
+    SHORT_PIPS_11                                   = 0x1A,
302
+    SHORT_PIPS_12                                   = 0x1B,
303
+    SHORT_PIPS_13                                   = 0x1C,
304
+    SHORT_PIPS_14                                   = 0x1D,
305
+    SHORT_PIPS_15                                   = 0x1E,
306
+    SHORT_PIPS_16                                   = 0x1F,
307
+    DTMF_POUND                                      = 0x23,
308
+    DTMF_STAR                                       = 0x2C,
309
+    DTMF_0                                          = 0x30,
310
+    DTMF_1                                          = 0x31,
311
+    DTMF_2                                          = 0x32,
312
+    DTMF_3                                          = 0x33,
313
+    DTMF_4                                          = 0x34,
314
+    DTMF_5                                          = 0x35,
315
+    DTMF_6                                          = 0x36,
316
+    DTMF_7                                          = 0x37,
317
+    DTMF_8                                          = 0x38,
318
+    DTMF_9                                          = 0x39,
319
+    HARP                                            = 0x40,
320
+    XYLOPHONE                                       = 0x41,
321
+    TUBA                                            = 0x42,
322
+    GLOCKENSPIEL                                    = 0x43,
323
+    ORGAN                                           = 0x44,
324
+    TRUMPET                                         = 0x45,
325
+    PIANO                                           = 0x46,
326
+    CHIMES                                          = 0x47,
327
+    MUSIC_BOX                                       = 0x48,
328
+    BELL                                            = 0x49,
329
+    CLICK                                           = 0x50,
330
+    SWITCH                                          = 0x51,
331
+    COWBELL                                         = 0x52,
332
+    NOTCH                                           = 0x53,
333
+    HIHAT                                           = 0x54,
334
+    KICKDRUM                                        = 0x55,
335
+    POP                                             = 0x56,
336
+    CLACK                                           = 0x57,
337
+    CHACK                                           = 0x58,
338
+    MUTE                                            = 0x60,
339
+    UNMUTE                                          = 0x61
340
+  };
341
+
342
+  enum note_t {
343
+    END_SONG                                        = 0xFF,
344
+    REST                                            = 0x00,
345
+
346
+    NOTE_C1                                         = 0x18, // 24
347
+    NOTE_C1S                                        = 0x19,
348
+    NOTE_D1                                         = 0x1A,
349
+    NOTE_D1S                                        = 0x1B,
350
+    NOTE_E1                                         = 0x1C,
351
+    NOTE_F1                                         = 0x1D,
352
+    NOTE_F1S                                        = 0x1E,
353
+    NOTE_G1                                         = 0x1F,
354
+    NOTE_G1S                                        = 0x20,
355
+    NOTE_A1                                         = 0x21,
356
+    NOTE_A1S                                        = 0x22,
357
+    NOTE_B1                                         = 0x23,
358
+
359
+    NOTE_C2                                         = 0x24,  //36
360
+    NOTE_C2S                                        = 0x25,
361
+    NOTE_D2                                         = 0x26,
362
+    NOTE_D2S                                        = 0x27,
363
+    NOTE_E2                                         = 0x28,
364
+    NOTE_F2                                         = 0x29,
365
+    NOTE_F2S                                        = 0x2A,
366
+    NOTE_G2                                         = 0x2B,
367
+    NOTE_G2S                                        = 0x2C,
368
+    NOTE_A2                                         = 0x2D,
369
+    NOTE_A2S                                        = 0x2E,
370
+    NOTE_B2                                         = 0x2F,
371
+
372
+    NOTE_C3                                         = 0x30,
373
+    NOTE_C3S                                        = 0x31,
374
+    NOTE_D3                                         = 0x32,
375
+    NOTE_D3S                                        = 0x33,
376
+    NOTE_E3                                         = 0x34,
377
+    NOTE_F3                                         = 0x35,
378
+    NOTE_F3S                                        = 0x36,
379
+    NOTE_G3                                         = 0x37,
380
+    NOTE_G3S                                        = 0x38,
381
+    NOTE_A3                                         = 0x39,
382
+    NOTE_A3S                                        = 0x3A,
383
+    NOTE_B3                                         = 0x3B,
384
+
385
+    NOTE_C4                                         = 0x3C,
386
+    NOTE_C4S                                        = 0x3D,
387
+    NOTE_D4                                         = 0x3E,
388
+    NOTE_D4S                                        = 0x3F,
389
+    NOTE_E4                                         = 0x40,
390
+    NOTE_F4                                         = 0x41,
391
+    NOTE_F4S                                        = 0x42,
392
+    NOTE_G4                                         = 0x43,
393
+    NOTE_G4S                                        = 0x44,
394
+    NOTE_A4                                         = 0x45,
395
+    NOTE_A4S                                        = 0x46,
396
+    NOTE_B4                                         = 0x47,
397
+
398
+    NOTE_C5                                         = 0x48,
399
+    NOTE_C5S                                        = 0x49,
400
+    NOTE_D5                                         = 0x4A,
401
+    NOTE_D5S                                        = 0x4B,
402
+    NOTE_E5                                         = 0x4C,
403
+    NOTE_F5                                         = 0x4D,
404
+    NOTE_F5S                                        = 0x4E,
405
+    NOTE_G5                                         = 0x4F,
406
+    NOTE_G5S                                        = 0x50,
407
+    NOTE_A5                                         = 0x51,
408
+    NOTE_A5S                                        = 0x52,
409
+    NOTE_B5                                         = 0x53,
410
+  };
411
+}

+ 118
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/display_list.h View File

@@ -0,0 +1,118 @@
1
+/******************
2
+ * display_list.h *
3
+ *****************/
4
+
5
+/**********************************************************************************
6
+ * Adapted from:                                                                  *
7
+ *     https://github.com/RudolphRiedel/FT800-FT813                               *
8
+ *     By Rudolph Riedel                                                          *
9
+ *                                                                                *
10
+ * MIT License                                                                    *
11
+ *                                                                                *
12
+ * Copyright (c) 2017                                                             *
13
+ *                                                                                *
14
+ * Permission is hereby granted, free of charge, to any person obtaining a copy   *
15
+ * of this software and associated documentation files (the "Software"), to deal  *
16
+ * in the Software without restriction, including without limitation the rights   *
17
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      *
18
+ * copies of the Software, and to permit persons to whom the Software is          *
19
+ * furnished to do so, subject to the following conditions:                       *
20
+ *                                                                                *
21
+ * The above copyright notice and this permission notice shall be included in all *
22
+ * copies or substantial portions of the Software.                                *
23
+ *                                                                                *
24
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     *
25
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       *
26
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE    *
27
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         *
28
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  *
29
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  *
30
+ * SOFTWARE.                                                                      *
31
+ *                                                                                *
32
+ **********************************************************************************/
33
+
34
+#pragma once
35
+
36
+namespace FTDI {
37
+  /* FT8xx graphics engine specific macros useful for static display list generation */
38
+  inline uint32_t ALPHA_FUNC(uint8_t func, uint8_t ref)        {return DL::ALPHA_FUNC|((func&7UL)<<8)|(ref&255UL);}
39
+  inline uint32_t BEGIN(begin_t prim)                          {return DL::BEGIN|(prim&15UL);}
40
+
41
+  inline uint32_t BITMAP_SOURCE(uint32_t ram_g_addr)           {return DL::BITMAP_SOURCE|(ram_g_addr & (FTDI::ftdi_memory_map::RAM_G_SIZE-1));}
42
+  inline uint32_t BITMAP_HANDLE(uint8_t handle)                {return DL::BITMAP_HANDLE|(handle&31UL);}
43
+  inline uint32_t BITMAP_LAYOUT(uint8_t format, uint16_t linestride, uint16_t height)
44
+                                                               {return DL::BITMAP_LAYOUT|((format&31UL)<<19)|((linestride&1023UL)<<9)|(height&511UL);}
45
+
46
+  inline uint32_t BITMAP_SIZE(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height)
47
+                                                               {return DL::BITMAP_SIZE|((filter&1UL)<<20)|((wrapx&1UL)<<19)|((wrapy&1UL)<<18)|((width&511UL)<<9)|(height&511UL);}
48
+  #if FTDI_API_LEVEL >= 810
49
+  inline uint32_t BITMAP_LAYOUT_H(uint8_t linestride, uint8_t height)
50
+                                                               {return DL::BITMAP_LAYOUT_H|((linestride&3UL)<<2)|(height&3UL);}
51
+  inline uint32_t BITMAP_SIZE_H(uint8_t width, uint8_t height)
52
+                                                               {return DL::BITMAP_SIZE_H|((width&3UL)<<2)|(height&3UL);}
53
+  #endif
54
+  inline uint32_t BITMAP_TRANSFORM_A(uint16_t a)               {return DL::BITMAP_TRANSFORM_A|(a&131071UL);}
55
+  inline uint32_t BITMAP_TRANSFORM_B(uint16_t b)               {return DL::BITMAP_TRANSFORM_B|(b&131071UL);}
56
+  inline uint32_t BITMAP_TRANSFORM_C(uint32_t c)               {return DL::BITMAP_TRANSFORM_C|(c&16777215UL);}
57
+  inline uint32_t BITMAP_TRANSFORM_D(uint16_t d)               {return DL::BITMAP_TRANSFORM_D|(d&131071UL);}
58
+  inline uint32_t BITMAP_TRANSFORM_E(uint16_t e)               {return DL::BITMAP_TRANSFORM_E|(e&131071UL);}
59
+  inline uint32_t BITMAP_TRANSFORM_F(uint32_t f)               {return DL::BITMAP_TRANSFORM_F|(f&16777215UL);}
60
+  inline uint32_t BLEND_FUNC(uint8_t src,uint8_t dst)          {return DL::BLEND_FUNC|((src&7UL)<<3)|(dst&7UL);}
61
+  inline uint32_t CALL(uint16_t dest)                          {return DL::CALL|(dest&65535UL);}
62
+  inline uint32_t CELL(uint8_t cell)                           {return DL::CELL|(cell&127UL);}
63
+  inline uint32_t CLEAR(bool c,bool s,bool t)                  {return DL::CLEAR|((c?1UL:0UL)<<2)|((s?1UL:0UL)<<1)|(t?1UL:0UL);}
64
+  inline uint32_t CLEAR_COLOR_A(uint8_t alpha)                 {return DL::CLEAR_COLOR_A|(alpha&255UL);}
65
+  inline uint32_t CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue)
66
+                                                               {return DL::CLEAR_COLOR_RGB|((red&255UL)<<16)|((green&255UL)<<8)|(blue&255UL);}
67
+  inline uint32_t CLEAR_COLOR_RGB(uint32_t rgb)                {return DL::CLEAR_COLOR_RGB|rgb;}
68
+  inline uint32_t CLEAR_STENCIL(uint8_t s)                     {return DL::CLEAR_STENCIL|(s&255UL);}
69
+  inline uint32_t CLEAR_TAG(uint8_t s)                         {return DL::CLEAR_TAG|(s&255UL);}
70
+  inline uint32_t COLOR_A(uint8_t alpha)                       {return DL::COLOR_A|(alpha&255UL);}
71
+  inline uint32_t COLOR_MASK(bool r, bool g, bool b, bool a)   {return DL::COLOR_MASK|((r?1UL:0UL)<<3)|((g?1UL:0UL)<<2)|((b?1UL:0UL)<<1)|(a?1UL:0UL);}
72
+  inline uint32_t COLOR_RGB(uint8_t red,uint8_t green,uint8_t blue)
73
+                                                               {return DL::COLOR_RGB|((red&255UL)<<16)|((green&255UL)<<8)|(blue&255UL);}
74
+  inline uint32_t COLOR_RGB(uint32_t rgb)                      {return DL::COLOR_RGB|rgb;}
75
+  /* inline uint32_t DISPLAY()                                 {return (0UL<<24)) */
76
+  inline uint32_t END()                                        {return DL::END;}
77
+  inline uint32_t JUMP(uint16_t dest)                          {return DL::JUMP|(dest&65535UL);}
78
+  inline uint32_t LINE_WIDTH(uint16_t width)                   {return DL::LINE_WIDTH|(width&4095UL);}
79
+  inline uint32_t MACRO(uint8_t m)                             {return DL::MACRO|(m&1UL);}
80
+  inline uint32_t POINT_SIZE(uint16_t size)                    {return DL::POINT_SIZE|(size&8191UL);}
81
+  inline uint32_t RESTORE_CONTEXT()                            {return DL::RESTORE_CONTEXT;}
82
+  inline uint32_t RETURN ()                                    {return DL::RETURN;}
83
+  inline uint32_t SAVE_CONTEXT()                               {return DL::SAVE_CONTEXT;}
84
+  inline uint32_t SCISSOR_XY(uint16_t x,uint16_t y) {
85
+    return DL::SCISSOR_XY |
86
+      (FTDI::ftdi_chip >= 810
87
+        ? ((x&2047UL)<<11)|(y&2047UL)
88
+        : ((x& 511UL)<<10)|(y&511UL));
89
+  }
90
+  inline uint32_t SCISSOR_SIZE(uint16_t w,uint16_t h) {
91
+    return DL::SCISSOR_SIZE |
92
+      (FTDI::ftdi_chip >= 810
93
+        ? ((w&4095UL)<<12)|(h&4095UL)
94
+        : ((w&1023UL)<<10)|(h&1023UL));
95
+  }
96
+  inline uint32_t SCISSOR_XY()                                 {return DL::SCISSOR_XY;}
97
+  inline uint32_t SCISSOR_SIZE() {
98
+    return DL::SCISSOR_SIZE |
99
+      (FTDI::ftdi_chip >= 810
100
+        ? (2048UL<<12)|(2048UL)
101
+        : ( 512UL<<10)|( 512UL));
102
+  }
103
+  inline uint32_t STENCIL_FUNC(uint16_t func, uint8_t ref, uint8_t mask)
104
+                                                               {return DL::STENCIL_FUNC|((func&7UL)<<16)|((ref&255UL)<<8)|(mask&255UL);}
105
+  inline uint32_t STENCIL_MASK(uint8_t mask)                   {return DL::STENCIL_MASK|(mask&255UL);}
106
+  inline uint32_t STENCIL_OP(uint8_t sfail, uint8_t spass)     {return DL::STENCIL_OP|(((sfail)&7UL)<<3)|(spass&7UL);}
107
+  inline uint32_t TAG(uint8_t s)                               {return DL::TAG|(s&255UL);}
108
+  inline uint32_t TAG_MASK(bool mask)                          {return DL::TAG_MASK|(mask?1:0);}
109
+  inline uint32_t VERTEX2F(uint16_t x, uint16_t y)             {return DL::VERTEX2F|((x&32767UL)<<15)|(y&32767UL);}
110
+  inline uint32_t VERTEX2II(uint16_t x,uint16_t y, uint8_t handle = 0, uint8_t cell = 0)
111
+                                                               {return DL::VERTEX2II|((x&511UL)<<21)|((y&511UL)<<12)|((handle&31UL)<<7)|(cell&127UL);}
112
+
113
+  #if FTDI_API_LEVEL >= 810
114
+  inline uint32_t VERTEX_FORMAT(uint8_t frac)                  {return DL::VERTEX_FORMAT|(frac&7UL);}
115
+  inline uint32_t VERTEX_TRANSLATE_X(int32_t x)                {return DL::VERTEX_TRANSLATE_X|(x&131071UL);}
116
+  inline uint32_t VERTEX_TRANSLATE_Y(int32_t y)                {return DL::VERTEX_TRANSLATE_Y|(y&131071UL);}
117
+  #endif
118
+}

+ 40
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/ftdi_basic.h View File

@@ -0,0 +1,40 @@
1
+/****************
2
+ * ftdi_basic.h *
3
+ ****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2019 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2019 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+#include "../compat.h"
26
+
27
+#if !defined(__MARLIN_FIRMWARE__)
28
+  #define FTDI_BASIC
29
+#endif
30
+
31
+#ifdef FTDI_BASIC
32
+  #include "registers_ft800.h"
33
+  #include "registers_ft810.h"
34
+  #include "constants.h"
35
+  #include "boards.h"
36
+  #include "commands.h"
37
+  #include "spi.h"
38
+  #include "display_list.h"
39
+  #include "resolutions.h"
40
+#endif

+ 150
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft800.h View File

@@ -0,0 +1,150 @@
1
+/*********************
2
+ * registers_ft800.h *
3
+ *********************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+/****************************************************************************
24
+ * This header defines registers for the FTDI FT800 LCD Driver chip.        *
25
+ ****************************************************************************/
26
+
27
+/*******************************************************************************
28
+ * FT810                                                                       *
29
+ *                                                                             *
30
+ * START    END ADDR   SIZE    NAME           DESCRIPTION                      *
31
+ *                                                                             *
32
+ * 0x000000 0x03FFFF   256 kB  RAM_G          Main Graphics RAM                *
33
+ *                                                                             *
34
+ * 0x0C0000 0x0C0003     4  B  ROM_CHIPID     [0:1] 0x800   Chip Id            *
35
+ *                                            [1:2] 0x0100  Vers ID            *
36
+ *                                                                             *
37
+ * 0x0BB23C 0x0FFFFB   275 kB  ROM_FONT       Font table and bitmap            *
38
+ *                                                                             *
39
+ * 0x0FFFFC 0x0FFFFF     4  B  ROM_FONT_ADDR  Font table pointer address       *
40
+ *                                                                             *
41
+ * 0x100000 0x101FFF     8 kB  RAM_DL         Display List RAM                 *
42
+ *                                                                             *
43
+ * 0x102000 0x1023FF     1 kB  RAM_PAL        Palette RAM                      *
44
+ *                                                                             *
45
+ * 0x102400 0x10257F   380  B  *          Registers                        *
46
+ *                                                                             *
47
+ * 0x108000 0x108FFF     4 kB  RAM_CMD        Command Buffer                   *
48
+ *                                                                             *
49
+ *******************************************************************************/
50
+
51
+#pragma once
52
+
53
+namespace FTDI {
54
+  struct ft800_memory_map {
55
+
56
+    //         MEMORY LOCATIONS     FT800
57
+    static constexpr uint32_t RAM_G          = 0x000000;   // Main Graphics RAM
58
+    static constexpr uint32_t ROM_CHIPID     = 0x0C0000;   // Chip ID/Version ID
59
+    static constexpr uint32_t ROM_FONT       = 0x0BB23C;   // Font ROM
60
+    static constexpr uint32_t ROM_FONT_ADDR  = 0x0FFFFC;   // Font Table Pointer
61
+    static constexpr uint32_t RAM_DL         = 0x100000;   // Display List RAM
62
+    static constexpr uint32_t RAM_PAL        = 0x102000;   // Palette RAM
63
+    static constexpr uint32_t RAM_REG        = 0x102400;   // Registers
64
+    static constexpr uint32_t RAM_CMD        = 0x108000;   // Command Buffer
65
+
66
+    static constexpr uint32_t RAM_G_SIZE     = 256*1024l;  // 256k
67
+  };
68
+
69
+  struct ft800_registers {
70
+    // REGISTERS AND ADDRESSES    FT800
71
+
72
+    //             REGISTER              ADDRESS       SIZE    RESET VALUE     TYPE     DESCRIPTION
73
+
74
+    static constexpr uint32_t ID                = 0x102400;  //    8    0x7C               r     Identification Register, Always 0x7C
75
+    static constexpr uint32_t FRAMES            = 0x102404;  //   32    0x00000000         r     Frame Counter, Since Reset
76
+    static constexpr uint32_t CLOCK             = 0x102408;  //   32    0x00000000         r     Clock cycles, Since Reset
77
+    static constexpr uint32_t FREQUENCY         = 0x10240C;  //   28    0x03938700       r/w     Main Clock Frequency
78
+    static constexpr uint32_t RENDERMODE        = 0x102410;  //    1    0x00             r/w     Rendering Mode: 0 = normal, 1 = single-line
79
+    static constexpr uint32_t SNAPY             = 0x102414;  //   11    0x0000           r/w     Scan Line Select for RENDERMODE 1
80
+    static constexpr uint32_t SNAPSHOT          = 0x102418;  //    1    -                  r     Trigger for RENDERMODE 1
81
+    static constexpr uint32_t CPURESET          = 0x10241C;  //    3    0x02             r/w     RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics
82
+    static constexpr uint32_t TAP_CRC           = 0x102420;  //   32    -                  r     Live Video Tap
83
+    static constexpr uint32_t TAP_MASK          = 0x102424;  //   32    0xFFFFFFFF       r/w     Live Video Tap Mask
84
+    static constexpr uint32_t HCYCLE            = 0x102428;  //   12    0x224            r/w     Horizontal Total Cycle Count
85
+    static constexpr uint32_t HOFFSET           = 0x10242C;  //   12    0x02B            r/w     Horizontal Display Start Offset
86
+    static constexpr uint32_t HSIZE             = 0x102430;  //   12    0x1E0            r/w     Horizontal Display Pixel Count
87
+    static constexpr uint32_t HSYNC0            = 0x102434;  //   12    0x000            r/w     Horizontal Sync Fall Offset
88
+    static constexpr uint32_t HSYNC1            = 0x102438;  //   12    0x029            r/w     Horizontal Sync Rise Offset
89
+    static constexpr uint32_t VCYCLE            = 0x10243C;  //   12    0x124            r/w     Vertical Total Cycle Count
90
+    static constexpr uint32_t VOFFSET           = 0x102440;  //   12    0x00C            r/w     Vertical Display Start Offset
91
+    static constexpr uint32_t VSIZE             = 0x102444;  //   12    0x110            r/w     Vertical Display Line Count
92
+    static constexpr uint32_t VSYNC0            = 0x102448;  //   10    0x000            r/w     Vertical Sync Fall Offset
93
+    static constexpr uint32_t VSYNC1            = 0x10244C;  //   10    0x00A            r/w     Vertical Sync Rise Offset
94
+    static constexpr uint32_t DLSWAP            = 0x102450;  //    2    0x00             r/w     Display List Swap Control
95
+    static constexpr uint32_t ROTATE            = 0x102454;  //    3    0x00             r/w     Screen 90,180, 270 degree rotate
96
+    static constexpr uint32_t OUTBITS           = 0x102458;  //    9    0x1B6            r/w     Output Resolution, 3x3x3 Bits
97
+    static constexpr uint32_t DITHER            = 0x10245C;  //    1    0x01             r/w     Output Dither Enable
98
+    static constexpr uint32_t SWIZZLE           = 0x102460;  //    4    0x00             r/w     Output RGB Swizzle, Pin Change for PCB Routing
99
+    static constexpr uint32_t CSPREAD           = 0x102464;  //    1    0x01             r/w     Output Clock Spreading Enable
100
+    static constexpr uint32_t PCLK_POL          = 0x102468;  //    1    0x00             r/w     PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge
101
+    static constexpr uint32_t PCLK              = 0x10246C;  //    8    0x00             r/w     PCLK Frequency Divider, 0 = Disable Clock
102
+    static constexpr uint32_t TAG_X             = 0x102470;  //   11    0x000            r/w     Tag Query X Coordinate
103
+    static constexpr uint32_t TAG_Y             = 0x102474;  //   11    0x000            r/w     Tag Query Y Coordinate
104
+    static constexpr uint32_t TAG               = 0x102478;  //    8    0x00               r     Tag Query Result
105
+    static constexpr uint32_t VOL_PB            = 0x10247C;  //    8    0xFF             r/w     Audio Playback Volume
106
+    static constexpr uint32_t VOL_SOUND         = 0x102480;  //    8    0xFF             r/w     Audio Synthesizer Volume
107
+    static constexpr uint32_t SOUND             = 0x102484;  //   16    0x0000           r/w     Audio Sound Effect Select
108
+    static constexpr uint32_t PLAY              = 0x102488;  //    1    0x00             r/w     Audio Start Effect Playback
109
+    static constexpr uint32_t GPIO_DIR          = 0x10248C;  //    8    0x80             r/w     GPIO Pin Direction: 0 = Input , 1 = Output
110
+    static constexpr uint32_t GPIO              = 0x102490;  //    8    0x00             r/w     GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6
111
+    static constexpr uint32_t INT_FLAGS         = 0x102498;  //    8    0x00               r     Interrupt Flags, Clear by Reading
112
+    static constexpr uint32_t INT_EN            = 0x10249C;  //    1    0x00             r/w     Global Interrupt Enable
113
+    static constexpr uint32_t INT_MASK          = 0x1024A0;  //    8    0xFF             r/w     Interrupt Enable Mask
114
+    static constexpr uint32_t PLAYBACK_START    = 0x1024A4;  //   20    0x00000          r/w     Audio Playback RAM Start Address
115
+    static constexpr uint32_t PLAYBACK_LENGTH   = 0x1024A8;  //   20    0x00000          r/w     Audio Playback Sample Length (Bytes)
116
+    static constexpr uint32_t PLAYBACK_READPTR  = 0x1024AC;  //   20    -                  r     Audio Playback Read Pointer
117
+    static constexpr uint32_t PLAYBACK_FREQ     = 0x1024B0;  //   16    0x1F40           r/w     Audio Playback Frequency (Hz)
118
+    static constexpr uint32_t PLAYBACK_FORMAT   = 0x1024B4;  //    2    0x00             r/w     Audio Playback Format
119
+    static constexpr uint32_t PLAYBACK_LOOP     = 0x1024B8;  //    1    0x00             r/w     Audio Playback Loop Enable
120
+    static constexpr uint32_t PLAYBACK_PLAY     = 0x1024BC;  //    1    0x00               r     Audio Start Playback
121
+    static constexpr uint32_t PWM_HZ            = 0x1024C0;  //   14    0x00FA           r/w     Backlight PWM Frequency (Hz)
122
+    static constexpr uint32_t PWM_DUTY          = 0x1024C4;  //    8    0x80             r/w     Backlight PWM Duty Cycle: 0 = 0%, 128 = 100%
123
+    static constexpr uint32_t MACRO_0           = 0x1024C8;  //   32    0x00000000       r/w     Display List Macro Command 0
124
+    static constexpr uint32_t MACRO_1           = 0x1024CC;  //   32    0x00000000       r/w     Display List Macro Command 1
125
+    static constexpr uint32_t CMD_READ          = 0x1024E4;  //   12    0x000            r/w     Command Buffer Read Pointer
126
+    static constexpr uint32_t CMD_WRITE         = 0x1024E8;  //   12    0x000            r/w     Command Buffer Write Pointer
127
+    static constexpr uint32_t CMD_DL            = 0x1024EC;  //   13    0x0000           r/w     Command Display List Offset
128
+    static constexpr uint32_t TOUCH_MODE        = 0x1024F0;  //    2    0x03             r/w     Touch-Screen Sampling Mode
129
+    static constexpr uint32_t TOUCH_ADC_MODE    = 0x1024F4;  //    1    0x01             r/w     Select Single Ended or Differential Sampling
130
+    static constexpr uint32_t TOUCH_CHARGE      = 0x1024F8;  //   16    0x1770           r/w     Touch Screen Charge Time, n x 6 Clocks
131
+    static constexpr uint32_t TOUCH_SETTLE      = 0x1024FC;  //    4    0x03             r/w     Touch-Screen Settle Time, n x 6 Clocks
132
+    static constexpr uint32_t TOUCH_OVERSAMPLE  = 0x102500;  //    4    0x07             r/w     Touch-Screen Oversample Factor
133
+    static constexpr uint32_t TOUCH_RZTHRESH    = 0x102504;  //   16    0xFFFF           r/w     Touch-Screen Resistance Threshold
134
+    static constexpr uint32_t TOUCH_RAW_XY      = 0x102508;  //   32    -                  r     Touch-Screen Raw (x-MSB16; y-LSB16)
135
+    static constexpr uint32_t TOUCH_RZ          = 0x10250C;  //   16    -                  r     Touch-Screen Resistance
136
+    static constexpr uint32_t TOUCH_SCREEN_XY   = 0x102510;  //   32    -                  r     Touch-Screen Screen (x-MSB16; y-LSB16)
137
+    static constexpr uint32_t TOUCH_TAG_XY      = 0x102514;  //   32    -                  r     Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16)
138
+    static constexpr uint32_t TOUCH_TAG         = 0x102518;  //    8    -                  r     Touch-Screen Tag 0 Result
139
+    static constexpr uint32_t TOUCH_TRANSFORM_A = 0x10251C;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient A (s15.16)
140
+    static constexpr uint32_t TOUCH_TRANSFORM_B = 0x102520;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient B (s15.16)
141
+    static constexpr uint32_t TOUCH_TRANSFORM_C = 0x102524;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient C (s15.16)
142
+    static constexpr uint32_t TOUCH_TRANSFORM_D = 0x102528;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient D (s15.16)
143
+    static constexpr uint32_t TOUCH_TRANSFORM_E = 0x10252C;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient E (s15.16)
144
+    static constexpr uint32_t TOUCH_TRANSFORM_F = 0x102530;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient F (s15.16)
145
+  //               Reserved Addresses      0x102434 - 0x102470
146
+    static constexpr uint32_t TOUCH_DIRECT_XY   = 0x102574;  //   32    -                  r     Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16)
147
+    static constexpr uint32_t TOUCH_DIRECT_Z1Z2 = 0x102578;  //   32    -                  r     Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16)
148
+    static constexpr uint32_t TRACKER           = 0x109000;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8)
149
+  };
150
+}

+ 185
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft810.h View File

@@ -0,0 +1,185 @@
1
+/*********************
2
+ * registers_ft810.h *
3
+ *********************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+/****************************************************************************
24
+ * This header defines registers for the FTDI FT810 LCD Driver chip.        *
25
+ ****************************************************************************/
26
+
27
+/*******************************************************************************
28
+ * FT810                                                                       *
29
+ *                                                                             *
30
+ * START    END ADDR   SIZE    NAME           DESCRIPTION                      *
31
+ *                                                                             *
32
+ * 0x000000 0x0FFFFF  1024 kB  RAM_G          Main Graphics RAM (0 to 1048572) *
33
+ *                                                                             *
34
+ * 0x0C0000 0x0C0003     4  B  ROM_CHIPID     [0:1] 0x800   Chip Id            *
35
+ *                                            [1:2] 0x0100  Vers ID            *
36
+ *                                                                             *
37
+ * 0x1E0000 0x2FFFFB  1152 kB  ROM_FONT       Font table and bitmap            *
38
+ *                                                                             *
39
+ * 0x2FFFFC 0x2FFFFF     4  B  ROM_FONT_ADDR  Font table pointer address       *
40
+ *                                                                             *
41
+ * 0x300000 0x301FFF     8 kB  RAM_DL         Display List RAM                 *
42
+ *                                                                             *
43
+ * 0x302000 0x302FFF     4 kB  *          Registers                        *
44
+ *                                                                             *
45
+ * 0x308000 0x308FFF     4 kB  RAM_CMD        Command Buffer                   *
46
+ *                                                                             *
47
+ *******************************************************************************/
48
+
49
+#pragma once
50
+
51
+namespace FTDI {
52
+  struct ft810_memory_map {
53
+    //         MEMORY LOCATIONS     FT810
54
+    static constexpr uint32_t RAM_G          = 0x000000;   // Main Graphics RAM
55
+    static constexpr uint32_t ROM_CHIPID     = 0x0C0000;   // Chip ID/Version ID
56
+    static constexpr uint32_t ROM_FONT       = 0x1E0000;   // Font ROM
57
+    static constexpr uint32_t ROM_FONT_ADDR  = 0x2FFFFC;   // Font Table Pointer
58
+    static constexpr uint32_t RAM_DL         = 0x300000;   // Display List RAM
59
+    static constexpr uint32_t RAM_REG        = 0x302000;   // Registers
60
+    static constexpr uint32_t RAM_CMD        = 0x308000;   // Command Buffer
61
+
62
+    static constexpr uint32_t RAM_G_SIZE     = 1024*1024l; // 1024k
63
+  };
64
+
65
+  struct ft810_registers {
66
+    // REGISTERS AND ADDRESSES    FT810
67
+
68
+    //             REGISTER              ADDRESS       SIZE    RESET VALUE     TYPE     DESCRIPTION
69
+
70
+    static constexpr uint32_t ID                = 0x302000;  //    8    0x7C               r     Identification Register, Always 0x7C
71
+    static constexpr uint32_t FRAMES            = 0x302004;  //   32    0x00000000         r     Frame Counter, Since Reset
72
+    static constexpr uint32_t CLOCK             = 0x302008;  //   32    0x00000000         r     Clock cycles, Since Reset
73
+    static constexpr uint32_t FREQUENCY         = 0x30200C;  //   28    0x03938700       r/w     Main Clock Frequency
74
+    static constexpr uint32_t RENDERMODE        = 0x302010;  //    1    0x00             r/w     Rendering Mode: 0 = normal, 1 = single-line
75
+    static constexpr uint32_t SNAPY             = 0x302014;  //   11    0x0000           r/w     Scan Line Select for RENDERMODE 1
76
+    static constexpr uint32_t SNAPSHOT          = 0x302018;  //    1    -                  r     Trigger for RENDERMODE 1
77
+    static constexpr uint32_t SNAPFORMAT        = 0x30201C;  //    6    0x20             r/w     Pixel Format for Scanline Readout
78
+    static constexpr uint32_t CPURESET          = 0x302020;  //    3    0x02             r/w     RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics
79
+    static constexpr uint32_t TAP_CRC           = 0x302024;  //   32    -                  r     Live Video Tap
80
+    static constexpr uint32_t TAP_MASK          = 0x302028;  //   32    0xFFFFFFFF       r/w     Live Video Tap Mask
81
+    static constexpr uint32_t HCYCLE            = 0x30202C;  //   12    0x224            r/w     Horizontal Total Cycle Count
82
+    static constexpr uint32_t HOFFSET           = 0x302030;  //   12    0x02B            r/w     Horizontal Display Start Offset
83
+    static constexpr uint32_t HSIZE             = 0x302034;  //   12    0x1E0            r/w     Horizontal Display Pixel Count
84
+    static constexpr uint32_t HSYNC0            = 0x302038;  //   12    0x000            r/w     Horizontal Sync Fall Offset
85
+    static constexpr uint32_t HSYNC1            = 0x30203C;  //   12    0x029            r/w     Horizontal Sync Rise Offset
86
+    static constexpr uint32_t VCYCLE            = 0x302040;  //   12    0x124            r/w     Vertical Total Cycle Count
87
+    static constexpr uint32_t VOFFSET           = 0x302044;  //   12    0x00C            r/w     Vertical Display Start Offset
88
+    static constexpr uint32_t VSIZE             = 0x302048;  //   12    0x110            r/w     Vertical Display Line Count
89
+    static constexpr uint32_t VSYNC0            = 0x30204C;  //   10    0x000            r/w     Vertical Sync Fall Offset
90
+    static constexpr uint32_t VSYNC1            = 0x302050;  //   10    0x00A            r/w     Vertical Sync Rise Offset
91
+    static constexpr uint32_t DLSWAP            = 0x302054;  //    2    0x00             r/w     Display List Swap Control
92
+    static constexpr uint32_t ROTATE            = 0x302058;  //    3    0x00             r/w     Screen 90,180, 270 degree rotate
93
+    static constexpr uint32_t OUTBITS           = 0x30205C;  //    9    0x1B6            r/w     Output Resolution, 3x3x3 Bits
94
+    static constexpr uint32_t DITHER            = 0x302060;  //    1    0x01             r/w     Output Dither Enable
95
+    static constexpr uint32_t SWIZZLE           = 0x302064;  //    4    0x00             r/w     Output RGB Swizzle, Pin Change for PCB Routing
96
+    static constexpr uint32_t CSPREAD           = 0x302068;  //    1    0x01             r/w     Output Clock Spreading Enable
97
+    static constexpr uint32_t PCLK_POL          = 0x30206C;  //    1    0x00             r/w     PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge
98
+    static constexpr uint32_t PCLK              = 0x302070;  //    8    0x00             r/w     PCLK Frequency Divider, 0 = Disable Clock
99
+    static constexpr uint32_t TAG_X             = 0x302074;  //   11    0x000            r/w     Tag Query X Coordinate
100
+    static constexpr uint32_t TAG_Y             = 0x302078;  //   11    0x000            r/w     Tag Query Y Coordinate
101
+    static constexpr uint32_t TAG               = 0x30207C;  //    8    0x00               r     Tag Query Result
102
+    static constexpr uint32_t VOL_PB            = 0x302080;  //    8    0xFF             r/w     Audio Playback Volume
103
+    static constexpr uint32_t VOL_SOUND         = 0x302084;  //    8    0xFF             r/w     Audio Synthesizer Volume
104
+    static constexpr uint32_t SOUND             = 0x302088;  //   16    0x0000           r/w     Audio Sound Effect Select
105
+    static constexpr uint32_t PLAY              = 0x30208C;  //    1    0x00             r/w     Audio Start Effect Playback
106
+    static constexpr uint32_t GPIO_DIR          = 0x302090;  //    8    0x80             r/w     GPIO Pin Direction: 0 = Input , 1 = Output
107
+    static constexpr uint32_t GPIO              = 0x302094;  //    8    0x00             r/w     GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6
108
+    static constexpr uint32_t GPIOX_DIR         = 0x302098;  //   16    0x8000           r/w     Extended GPIO Pin Direction
109
+    static constexpr uint32_t GPIOX             = 0x30209C;  //   16    0x0080           r/w     Extended GPIO Pin Values
110
+    //             Reserved Addr           0x3020A0
111
+    //             Reserved Addr           0x3020A4
112
+    static constexpr uint32_t INT_FLAGS         = 0x3020A8;  //    8    0x00               r     Interrupt Flags, Clear by Reading
113
+    static constexpr uint32_t INT_EN            = 0x3020AC;  //    1    0x00             r/w     Global Interrupt Enable
114
+    static constexpr uint32_t INT_MASK          = 0x3020B0;  //    8    0xFF             r/w     Interrupt Enable Mask
115
+    static constexpr uint32_t PLAYBACK_START    = 0x3020B4;  //   20    0x00000          r/w     Audio Playback RAM Start Address
116
+    static constexpr uint32_t PLAYBACK_LENGTH   = 0x3020B8;  //   20    0x00000          r/w     Audio Playback Sample Length (Bytes)
117
+    static constexpr uint32_t PLAYBACK_READPTR  = 0x3020BC;  //   20    -                  r     Audio Playback Read Pointer
118
+    static constexpr uint32_t PLAYBACK_FREQ     = 0x3020C0;  //   16    0x1F40           r/w     Audio Playback Frequency (Hz)
119
+    static constexpr uint32_t PLAYBACK_FORMAT   = 0x3020C4;  //    2    0x00             r/w     Audio Playback Format
120
+    static constexpr uint32_t PLAYBACK_LOOP     = 0x3020C8;  //    1    0x00             r/w     Audio Playback Loop Enable
121
+    static constexpr uint32_t PLAYBACK_PLAY     = 0x3020CC;  //    1    0x00               r     Audio Start Playback
122
+    static constexpr uint32_t PWM_HZ            = 0x3020D0;  //   14    0x00FA           r/w     Backlight PWM Frequency (Hz)
123
+    static constexpr uint32_t PWM_DUTY          = 0x3020D4;  //    8    0x80             r/w     Backlight PWM Duty Cycle: 0 = 0%, 128 = 100%
124
+    static constexpr uint32_t MACRO_0           = 0x3020D8;  //   32    0x00000000       r/w     Display List Macro Command 0
125
+    static constexpr uint32_t MACRO_1           = 0x3020DC;  //   32    0x00000000       r/w     Display List Macro Command 1
126
+    //             Reserved Addr           0x3020E0
127
+    //             Reserved Addr           0x3020E4
128
+    //             Reserved Addr           0x3020E8
129
+    //             Reserved Addr           0x3020EC
130
+    //             Reserved Addr           0x3020F0
131
+    //             Reserved Addr           0x3020F4
132
+    static constexpr uint32_t CMD_READ          = 0x3020F8;  //   12    0x000            r/w     Command Buffer Read Pointer
133
+    static constexpr uint32_t CMD_WRITE         = 0x3020FC;  //   12    0x000            r/w     Command Buffer Write Pointer
134
+    static constexpr uint32_t CMD_DL            = 0x302100;  //   13    0x0000           r/w     Command Display List Offset
135
+    static constexpr uint32_t TOUCH_MODE        = 0x302104;  //    2    0x03             r/w     Touch-Screen Sampling Mode
136
+    static constexpr uint32_t TOUCH_ADC_MODE    = 0x302108;  //    1    0x01             r/w     Select Single Ended or Differential Sampling
137
+    static constexpr uint32_t TOUCH_CHARGE      = 0x30210C;  //   16    0x1770           r/w     Touch Screen Charge Time, n x 6 Clocks
138
+    static constexpr uint32_t TOUCH_SETTLE      = 0x302110;  //    4    0x03             r/w     Touch-Screen Settle Time, n x 6 Clocks
139
+    static constexpr uint32_t TOUCH_OVERSAMPLE  = 0x302114;  //    4    0x07             r/w     Touch-Screen Oversample Factor
140
+    static constexpr uint32_t TOUCH_RZTHRESH    = 0x302118;  //   16    0xFFFF           r/w     Touch-Screen Resistance Threshold
141
+    static constexpr uint32_t TOUCH_RAW_XY      = 0x30211C;  //   32    -                  r     Touch-Screen Raw (x-MSB16; y-LSB16)
142
+    static constexpr uint32_t TOUCH_RZ          = 0x302120;  //   16    -                  r     Touch-Screen Resistance
143
+    static constexpr uint32_t TOUCH_SCREEN_XY   = 0x302124;  //   32    -                  r     Touch-Screen Screen (x-MSB16; y-LSB16)
144
+    static constexpr uint32_t TOUCH_TAG_XY      = 0x302128;  //   32    -                  r     Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16)
145
+    static constexpr uint32_t TOUCH_TAG         = 0x30212C;  //    8    -                  r     Touch-Screen Tag 0 Result
146
+    static constexpr uint32_t TOUCH_TAG1_XY     = 0x302130;  //   32    -                  r     Touch-Screen Tag 1 Lookup
147
+    static constexpr uint32_t TOUCH_TAG1        = 0x302134;  //    8    -                  r     Touch-Screen Tag 1 Result
148
+    static constexpr uint32_t TOUCH_TAG2_XY     = 0x302138;  //   32    -                  r     Touch-Screen Tag 2 Lookup
149
+    static constexpr uint32_t TOUCH_TAG2        = 0x30213C;  //    8    -                  r     Touch-Screen Tag 2 Result
150
+    static constexpr uint32_t TOUCH_TAG3_XY     = 0x302140;  //   32    -                  r     Touch-Screen Tag 3 Lookup
151
+    static constexpr uint32_t TOUCH_TAG3        = 0x302144;  //    8    -                  r     Touch-Screen Tag 3 Result
152
+    static constexpr uint32_t TOUCH_TAG4_XY     = 0x302148;  //   32    -                  r     Touch-Screen Tag 4 Lookup
153
+    static constexpr uint32_t TOUCH_TAG4        = 0x30214C;  //    8    -                  r     Touch-Screen Tag 4 Result
154
+    static constexpr uint32_t TOUCH_TRANSFORM_A = 0x302150;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient A (s15.16)
155
+    static constexpr uint32_t TOUCH_TRANSFORM_B = 0x302154;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient B (s15.16)
156
+    static constexpr uint32_t TOUCH_TRANSFORM_C = 0x302158;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient C (s15.16)
157
+    static constexpr uint32_t TOUCH_TRANSFORM_D = 0x30215C;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient D (s15.16)
158
+    static constexpr uint32_t TOUCH_TRANSFORM_E = 0x302160;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient E (s15.16)
159
+    static constexpr uint32_t TOUCH_TRANSFORM_F = 0x302164;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient F (s15.16)
160
+    static constexpr uint32_t TOUCH_CONFIG      = 0x302168;  //   16    0x8381           r/w     Touch Configuration
161
+    static constexpr uint32_t CTOUCH_TOUCH4_X   = 0x30216C;  //   16    -                  r     Extended Mode Touch Screen
162
+    //             Reserved Addresses      0x302170
163
+    static constexpr uint32_t BIST_EN           = 0x302174;  //    1    0                r/w     BIST Memory Mapping Enable
164
+    //             Reserved Addr           0x302178
165
+    //             Reserved Addr           0x30217C
166
+    static constexpr uint32_t TRIM              = 0x302180;  //    8    0                r/w     Internal Clock Trimming
167
+    static constexpr uint32_t ANA_COMP          = 0x302184;  //    8    0                r/w     Analog Control Register
168
+    static constexpr uint32_t SPI_WIDTH         = 0x302188;  //    3    0                r/w     QSPI Bus Width Setting
169
+    static constexpr uint32_t TOUCH_DIRECT_XY   = 0x30218C;  //   32    -                  r     Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16)
170
+    static constexpr uint32_t TOUCH_DIRECT_Z1Z2 = 0x302190;  //   32    -                  r     Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16)
171
+    //             Reserved Addresses      0x302194 - 0x302560
172
+    static constexpr uint32_t DATESTAMP         = 0x320564;  //  128    -                  r     Stamp Date Code
173
+    static constexpr uint32_t CMDB_SPACE        = 0x302574;  //   12    0xFFC            r/w     Command DL Space Available
174
+    static constexpr uint32_t CMDB_WRITE        = 0x302578;  //   32    0                  w     Command DL Write
175
+
176
+    static constexpr uint32_t TRACKER           = 0x309000;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8)
177
+    static constexpr uint32_t TRACKER_1         = 0x309004;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8)
178
+    static constexpr uint32_t TRACKER_2         = 0x309008;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8)
179
+    static constexpr uint32_t TRACKER_3         = 0x30900C;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8)
180
+    static constexpr uint32_t TRACKER_4         = 0x309010;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8)
181
+
182
+    static constexpr uint32_t MEDIAFIFO_READ    = 0x309014;  //   32    0x00000000       r/w     Media FIFO read pointer
183
+    static constexpr uint32_t MEDIAFIFO_WRITE   = 0x309018;  //   32    0x00000000       r/w     Media FIFO write pointer
184
+  };
185
+}

+ 128
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/resolutions.h View File

@@ -0,0 +1,128 @@
1
+/*****************
2
+ * resolutions.h *
3
+ *****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2019 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2019 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+/***
26
+ * The FT8xx has odd registers that don't correspond to timing values in
27
+ * display datasheets. This macro computes the register values using the
28
+ * formulas given in the document:
29
+ *
30
+ *     Bridgetek Application Note
31
+ *     AN_336 FT8xx
32
+ *     Selecting an LCD Display
33
+ *     Version 2.1
34
+ *     Issue Date: 2017-11-14
35
+ *
36
+ */
37
+#define COMPUTE_REGS_FROM_DATASHEET \
38
+    constexpr uint16_t Hoffset              = thfp + thb - 1; \
39
+    constexpr uint16_t Hcycle               = th; \
40
+    constexpr uint16_t Hsync0               = thfp - 1 ; \
41
+    constexpr uint16_t Hsync1               = thfp + thpw - 1; \
42
+    constexpr uint16_t Voffset              = tvfp + tvb - 1; \
43
+    constexpr uint16_t Vcycle               = tv; \
44
+    constexpr uint16_t Vsync0               = tvfp - 1; \
45
+    constexpr uint16_t Vsync1               = tvfp + tvpw - 1; \
46
+    static_assert(thfp + thb + Hsize == th, "Mismatch in display th"); \
47
+    static_assert(tvfp + tvb + Vsize == tv, "Mismatch in display tv");
48
+
49
+#ifdef TOUCH_UI_320x240
50
+  namespace FTDI {
51
+    constexpr uint8_t Pclk                 =    8;
52
+    constexpr uint8_t Pclkpol              =    0;
53
+    constexpr uint16_t Hsize               =  320;
54
+    constexpr uint16_t Vsize               =  240;
55
+    constexpr uint16_t Vsync0              =    0;
56
+    constexpr uint16_t Vsync1              =    2;
57
+    constexpr uint16_t Voffset             =   13;
58
+    constexpr uint16_t Vcycle              =  263;
59
+    constexpr uint16_t Hsync0              =    0;
60
+    constexpr uint16_t Hsync1              =   10;
61
+    constexpr uint16_t Hoffset             =   70;
62
+    constexpr uint16_t Hcycle              =  408;
63
+
64
+    constexpr uint32_t default_transform_a =  0x000054ad;
65
+    constexpr uint32_t default_transform_b =  0xffffff52;
66
+    constexpr uint32_t default_transform_c =  0xfff7f6e4;
67
+    constexpr uint32_t default_transform_d =  0x00000065;
68
+    constexpr uint32_t default_transform_e =  0xffffbe3b;
69
+    constexpr uint32_t default_transform_f =  0x00f68e75;
70
+  }
71
+
72
+#elif defined(TOUCH_UI_480x272)
73
+  namespace FTDI {
74
+    constexpr uint8_t  Pclk                 =    7;
75
+    constexpr uint8_t  Pclkpol              =    1;
76
+    constexpr uint16_t Hsize                =  480;
77
+    constexpr uint16_t Vsize                =  272;
78
+
79
+    constexpr uint16_t th                   =  525; // One horizontal line
80
+    constexpr uint16_t thfp                 =   43; // HS Front porch
81
+    constexpr uint16_t thb                  =    2; // HS Back porch (blanking)
82
+    constexpr uint16_t thpw                 =   41; // HS pulse width
83
+
84
+    constexpr uint16_t tv                   =  286; // Vertical period time
85
+    constexpr uint16_t tvfp                 =   12; // VS Front porch
86
+    constexpr uint16_t tvb                  =    2; // VS Back porch (blanking)
87
+    constexpr uint16_t tvpw                 =   10; // VS pulse width
88
+
89
+    COMPUTE_REGS_FROM_DATASHEET
90
+
91
+    constexpr uint32_t default_transform_a  =  0x00008100;
92
+    constexpr uint32_t default_transform_b  =  0x00000000;
93
+    constexpr uint32_t default_transform_c  =  0xFFF18000;
94
+    constexpr uint32_t default_transform_d  =  0x00000000;
95
+    constexpr uint32_t default_transform_e  =  0xFFFFB100;
96
+    constexpr uint32_t default_transform_f  =  0x0120D000;
97
+  }
98
+
99
+#elif defined(TOUCH_UI_800x480)
100
+  namespace FTDI {
101
+    constexpr uint8_t  Pclk                 =    3;
102
+    constexpr uint8_t  Pclkpol              =    1;
103
+    constexpr uint16_t Hsize                =  800;
104
+    constexpr uint16_t Vsize                =  480;
105
+
106
+    constexpr uint16_t th                   = 1056; // One horizontal line
107
+    constexpr uint16_t thfp                 =  210; // HS Front porch
108
+    constexpr uint16_t thb                  =   46; // HS Back porch (blanking)
109
+    constexpr uint16_t thpw                 =   23; // HS pulse width
110
+
111
+    constexpr uint16_t tv                   =  525; // Vertical period time
112
+    constexpr uint16_t tvfp                 =   22; // VS Front porch
113
+    constexpr uint16_t tvb                  =   23; // VS Back porch (blanking)
114
+    constexpr uint16_t tvpw                 =   10; // VS pulse width
115
+
116
+    COMPUTE_REGS_FROM_DATASHEET
117
+
118
+    constexpr uint32_t default_transform_a  =  0x0000D8B9;
119
+    constexpr uint32_t default_transform_b  =  0x00000124;
120
+    constexpr uint32_t default_transform_c  =  0xFFE23926;
121
+    constexpr uint32_t default_transform_d  =  0xFFFFFF51;
122
+    constexpr uint32_t default_transform_e  =  0xFFFF7E4F;
123
+    constexpr uint32_t default_transform_f  =  0x01F0AF70;
124
+  }
125
+
126
+#else
127
+  #error Unknown or no LULZBOT_TOUCH_UI display resolution specified. To add a display resolution, modify "ftdi_eve_resolutions.h"
128
+#endif

+ 178
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.cpp View File

@@ -0,0 +1,178 @@
1
+/***********
2
+ * spi.cpp *
3
+ ***********/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#include "ftdi_basic.h"
24
+
25
+#ifdef FTDI_BASIC
26
+
27
+/********************************* SPI Functions *********************************/
28
+
29
+namespace FTDI {
30
+  #if !defined(CLCD_USE_SOFT_SPI)
31
+    SPISettings SPI::spi_settings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0);
32
+  #endif
33
+
34
+  void SPI::spi_init (void) {
35
+    SET_OUTPUT(CLCD_MOD_RESET); // Module Reset (a.k.a. PD, not SPI)
36
+    WRITE(CLCD_MOD_RESET, 0); // start with module in power-down
37
+
38
+    SET_OUTPUT(CLCD_SPI_CS);
39
+    WRITE(CLCD_SPI_CS, 1);
40
+
41
+    #ifdef SPI_FLASH_SS
42
+      SET_OUTPUT(SPI_FLASH_SS);
43
+      WRITE(SPI_FLASH_SS, 1);
44
+    #endif
45
+
46
+    #ifdef CLCD_USE_SOFT_SPI
47
+      SET_OUTPUT(CLCD_SOFT_SPI_MOSI);
48
+      WRITE(CLCD_SOFT_SPI_MOSI, 1);
49
+
50
+      SET_OUTPUT(CLCD_SOFT_SPI_SCLK);
51
+      WRITE(CLCD_SOFT_SPI_SCLK, 0);
52
+
53
+      SET_INPUT_PULLUP(CLCD_SOFT_SPI_MISO);
54
+    #else
55
+      ::SPI.begin();
56
+    #endif
57
+  }
58
+
59
+  #ifdef CLCD_USE_SOFT_SPI
60
+    uint8_t SPI::_soft_spi_xfer (uint8_t spiOutByte) {
61
+      uint8_t spiIndex  = 0x80;
62
+      uint8_t spiInByte = 0;
63
+      uint8_t k;
64
+
65
+      noInterrupts();
66
+      for(k = 0; k <8; k++) {  // Output and Read each bit of spiOutByte and spiInByte
67
+        if (spiOutByte & spiIndex) {   // Output MOSI Bit
68
+          WRITE(CLCD_SOFT_SPI_MOSI, 1);
69
+        }
70
+        else {
71
+          WRITE(CLCD_SOFT_SPI_MOSI, 0);
72
+        }
73
+        WRITE(CLCD_SOFT_SPI_SCLK, 1);   // Pulse Clock
74
+        WRITE(CLCD_SOFT_SPI_SCLK, 0);
75
+
76
+        if (READ(CLCD_SOFT_SPI_MISO)) {
77
+          spiInByte |= spiIndex;
78
+        }
79
+
80
+        spiIndex >>= 1;
81
+      }
82
+      interrupts();
83
+      return spiInByte;
84
+    }
85
+  #endif
86
+
87
+  #ifdef CLCD_USE_SOFT_SPI
88
+    void SPI::_soft_spi_send (uint8_t spiOutByte) {
89
+      uint8_t spiIndex  = 0x80;
90
+      uint8_t k;
91
+
92
+      noInterrupts();
93
+      for(k = 0; k <8; k++) {         // Output each bit of spiOutByte
94
+        if (spiOutByte & spiIndex) {   // Output MOSI Bit
95
+          WRITE(CLCD_SOFT_SPI_MOSI, 1);
96
+        }
97
+        else {
98
+          WRITE(CLCD_SOFT_SPI_MOSI, 0);
99
+        }
100
+        WRITE(CLCD_SOFT_SPI_SCLK, 1);   // Pulse Clock
101
+        WRITE(CLCD_SOFT_SPI_SCLK, 0);
102
+
103
+        spiIndex >>= 1;
104
+      }
105
+      interrupts();
106
+    }
107
+  #endif
108
+
109
+  void SPI::spi_read_bulk (void *data, uint16_t len) {
110
+    uint8_t* p = (uint8_t *)data;
111
+    #if !defined(CLCD_USE_SOFT_SPI)
112
+      ::SPI.transfer(p, len);
113
+    #else
114
+      while (len--) *p++ = spi_recv();
115
+    #endif
116
+  }
117
+
118
+  bool SPI::spi_verify_bulk (const void *data, uint16_t len) {
119
+    const uint8_t* p = (const uint8_t *)data;
120
+    while (len--) if (*p++ != spi_recv()) return false;
121
+    return true;
122
+  }
123
+
124
+  // CLCD SPI - Chip Select
125
+  void SPI::spi_ftdi_select (void) {
126
+    #if !defined(CLCD_USE_SOFT_SPI)
127
+      ::SPI.beginTransaction(spi_settings);
128
+    #endif
129
+    WRITE(CLCD_SPI_CS, 0);
130
+    delayMicroseconds(1);
131
+  }
132
+
133
+  // CLCD SPI - Chip Deselect
134
+  void SPI::spi_ftdi_deselect (void) {
135
+    WRITE(CLCD_SPI_CS, 1);
136
+    #if !defined(CLCD_USE_SOFT_SPI)
137
+      ::SPI.endTransaction();
138
+    #endif
139
+  }
140
+
141
+  #ifdef SPI_FLASH_SS
142
+  // Serial SPI Flash SPI - Chip Select
143
+  void SPI::spi_flash_select () {
144
+    #if !defined(CLCD_USE_SOFT_SPI)
145
+    ::SPI.beginTransaction(spi_settings);
146
+    #endif
147
+    WRITE(SPI_FLASH_SS, 0);
148
+    delayMicroseconds(1);
149
+  }
150
+
151
+  // Serial SPI Flash SPI - Chip Deselect
152
+  void SPI::spi_flash_deselect () {
153
+    WRITE(SPI_FLASH_SS, 1);
154
+    #if !defined(CLCD_USE_SOFT_SPI)
155
+    ::SPI.endTransaction();
156
+    #endif
157
+  }
158
+  #endif
159
+
160
+  // Not really a SPI signal...
161
+  void SPI::ftdi_reset (void) {
162
+    WRITE(CLCD_MOD_RESET, 0);
163
+    delay(6); /* minimum time for power-down is 5ms */
164
+    WRITE(CLCD_MOD_RESET, 1);
165
+    delay(21); /* minimum time to allow from rising PD_N to first access is 20ms */
166
+  }
167
+
168
+  // Not really a SPI signal...
169
+  void SPI::test_pulse(void)
170
+  {
171
+    #ifdef CLCD_AUX_0
172
+      WRITE(CLCD_AUX_0, 1);
173
+      delayMicroseconds(10);
174
+      WRITE(CLCD_AUX_0, 0);
175
+    #endif
176
+  }
177
+}
178
+#endif // FTDI_BASIC

+ 128
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.h View File

@@ -0,0 +1,128 @@
1
+/*********
2
+ * spi.h *
3
+ *********/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+#if !defined(CLCD_USE_SOFT_SPI)
26
+  #include <SPI.h>
27
+#endif
28
+
29
+namespace FTDI {
30
+  namespace SPI {
31
+    #if !defined(CLCD_USE_SOFT_SPI)
32
+      extern SPISettings spi_settings;
33
+    #endif
34
+
35
+    uint8_t  _soft_spi_xfer (uint8_t val);
36
+    void     _soft_spi_send (uint8_t val);
37
+
38
+    void     spi_init           ();
39
+
40
+    void     spi_ftdi_select    ();
41
+    void     spi_ftdi_deselect  ();
42
+
43
+    void     spi_flash_select   ();
44
+    void     spi_flash_deselect ();
45
+
46
+    inline uint8_t spi_recv() {
47
+      #ifdef CLCD_USE_SOFT_SPI
48
+        return _soft_spi_xfer(0x00);
49
+      #else
50
+        return ::SPI.transfer(0x00);
51
+      #endif
52
+    };
53
+
54
+    inline void spi_send (uint8_t val) {
55
+      #ifdef CLCD_USE_SOFT_SPI
56
+        _soft_spi_send(val);
57
+      #else
58
+        ::SPI.transfer(val);
59
+      #endif
60
+    };
61
+
62
+    inline void       spi_write_8    (uint8_t val)    {spi_send(val);};
63
+    inline uint8_t    spi_read_8     ()               {return spi_recv();};
64
+
65
+    namespace least_significant_byte_first {
66
+      inline void     spi_write_16   (uint16_t val)   {spi_send(val >> 0);
67
+                                                       spi_send(val >> 8);};
68
+      inline void     spi_write_32   (uint32_t val)   {spi_send(val >> 0);
69
+                                                       spi_send(val >> 8);
70
+                                                       spi_send(val >> 16);
71
+                                                       spi_send(val >> 24);};
72
+
73
+      inline uint8_t  spi_read_8     ()               {return spi_recv();};
74
+      inline uint16_t spi_read_16    ()               {return (((uint16_t) spi_recv()) <<  0) |
75
+                                                              (((uint16_t) spi_recv()) <<  8);};
76
+      inline uint32_t spi_read_32    ()               {return (((uint32_t) spi_recv()) <<  0) |
77
+                                                              (((uint32_t) spi_recv()) <<  8) |
78
+                                                              (((uint32_t) spi_recv()) << 16) |
79
+                                                              (((uint32_t) spi_recv()) << 24);};
80
+    }
81
+
82
+    namespace most_significant_byte_first {
83
+      inline void     spi_write_16   (uint16_t val)   {spi_send(val >> 8);
84
+                                                       spi_send(val >> 0);};
85
+      inline void     spi_write_24   (uint32_t val)   {spi_send(val >> 16);
86
+                                                       spi_send(val >> 8);
87
+                                                       spi_send(val >> 0);};
88
+      inline void     spi_write_32   (uint32_t val)   {spi_send(val >> 24);
89
+                                                       spi_send(val >> 16);
90
+                                                       spi_send(val >> 8);
91
+                                                       spi_send(val >> 0);};
92
+
93
+      inline uint16_t spi_read_16    ()               {return (((uint16_t) spi_recv()) <<  8) |
94
+                                                              (((uint16_t) spi_recv()) <<  0);};
95
+      inline uint32_t spi_read_32    ()               {return (((uint32_t) spi_recv()) << 24) |
96
+                                                              (((uint32_t) spi_recv()) << 16) |
97
+                                                              (((uint32_t) spi_recv()) <<  8) |
98
+                                                              (((uint32_t) spi_recv()) <<  0);};
99
+    }
100
+
101
+    inline uint8_t ram_write(const uint8_t *p) {return *p;}
102
+    inline uint8_t pgm_write(const uint8_t *p) {return pgm_read_byte(p);}
103
+
104
+    typedef uint8_t (*bulk_write_op)(const uint8_t*);
105
+
106
+    // Generic template for function for writing multiple bytes, plus padding bytes.
107
+    // The template parameter op is an inlineable function which is applied to each byte.
108
+
109
+    template<bulk_write_op byte_op>
110
+    void spi_write_bulk(const void *data, uint16_t len, uint8_t padding) {
111
+      const uint8_t* p = (const uint8_t *)data;
112
+      while (len--)     spi_send(byte_op(p++));
113
+      while (padding--) spi_send(0);
114
+    }
115
+
116
+    template<bulk_write_op byte_op>
117
+    void spi_write_bulk(const void *data, uint16_t len) {
118
+      const uint8_t* p = (const uint8_t *)data;
119
+      while (len--) spi_send(byte_op(p++));
120
+    }
121
+
122
+    void spi_read_bulk(      void *data, uint16_t len);
123
+    bool spi_verify_bulk(const void *data, uint16_t len);
124
+
125
+    void ftdi_reset(void);
126
+    void test_pulse(void);
127
+  }
128
+}

+ 222
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/compat.h View File

@@ -0,0 +1,222 @@
1
+/****************************************************************************
2
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
3
+ *                                                                          *
4
+ *   This program is free software: you can redistribute it and/or modify   *
5
+ *   it under the terms of the GNU General Public License as published by   *
6
+ *   the Free Software Foundation, either version 3 of the License, or      *
7
+ *   (at your option) any later version.                                    *
8
+ *                                                                          *
9
+ *   This program is distributed in the hope that it will be useful,        *
10
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
11
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
12
+ *   GNU General Public License for more details.                           *
13
+ *                                                                          *
14
+ *   To view a copy of the GNU General Public License, go to the following  *
15
+ *   location: <http://www.gnu.org/licenses/>.                              *
16
+ ****************************************************************************/
17
+
18
+#pragma once
19
+
20
+#include "../config.h"
21
+
22
+#ifdef __MARLIN_FIRMWARE__
23
+
24
+  // Marlin will define the I/O functions for us
25
+  #if ENABLED(LULZBOT_TOUCH_UI)
26
+    #define FTDI_BASIC
27
+    #define FTDI_EXTENDED
28
+  #endif
29
+
30
+#else // !__MARLIN_FIRMWARE__
31
+
32
+  #include "Arduino.h"
33
+
34
+  #if !defined(CLCD_USE_SOFT_SPI)
35
+    #include "SPI.h"
36
+  #endif
37
+
38
+  namespace fast_io {
39
+
40
+    template<typename port_t,uint8_t bits>
41
+    struct port_pin {
42
+      typedef port_t port;
43
+      static inline void set_high()         {port::port() = (port::port() |   bits);}
44
+      static inline void set_low()          {port::port() = (port::port() & (~bits));}
45
+      static inline void set_input()        {port::ddr()  = (port::ddr()  & (~bits));}
46
+      static inline void set_input_pullup() {set_input(); set_high();}
47
+      static inline void set_output()       {port::ddr()  = (port::ddr()  |   bits);}
48
+      static inline uint8_t read()          {return port::pin() & bits;}
49
+      static inline void write(bool v)      {if (v) set_high(); else set_low();}
50
+    };
51
+
52
+    #define MAKE_AVR_PORT_PINS(ID) \
53
+      struct port_##ID { \
54
+        static volatile uint8_t &pin()  {return PIN##ID;}; \
55
+        static volatile uint8_t &port() {return PORT##ID;}; \
56
+        static volatile uint8_t &ddr()  {return DDR##ID;}; \
57
+      }; \
58
+      typedef port_pin<port_##ID, 0b00000001> AVR_##ID##0; \
59
+      typedef port_pin<port_##ID, 0b00000010> AVR_##ID##1; \
60
+      typedef port_pin<port_##ID, 0b00000100> AVR_##ID##2; \
61
+      typedef port_pin<port_##ID, 0b00001000> AVR_##ID##3; \
62
+      typedef port_pin<port_##ID, 0b00010000> AVR_##ID##4; \
63
+      typedef port_pin<port_##ID, 0b00100000> AVR_##ID##5; \
64
+      typedef port_pin<port_##ID, 0b01000000> AVR_##ID##6; \
65
+      typedef port_pin<port_##ID, 0b10000000> AVR_##ID##7;
66
+
67
+    #ifdef PORTA
68
+      MAKE_AVR_PORT_PINS(A);
69
+    #endif
70
+    #ifdef PORTB
71
+      MAKE_AVR_PORT_PINS(B);
72
+    #endif
73
+    #ifdef PORTC
74
+      MAKE_AVR_PORT_PINS(C);
75
+    #endif
76
+    #ifdef PORTD
77
+      MAKE_AVR_PORT_PINS(D);
78
+    #endif
79
+    #ifdef PORTE
80
+      MAKE_AVR_PORT_PINS(E);
81
+    #endif
82
+    #ifdef PORTF
83
+      MAKE_AVR_PORT_PINS(F);
84
+    #endif
85
+    #ifdef PORTG
86
+      MAKE_AVR_PORT_PINS(G);
87
+    #endif
88
+    #ifdef PORTH
89
+      MAKE_AVR_PORT_PINS(H);
90
+    #endif
91
+    #ifdef PORTJ
92
+      MAKE_AVR_PORT_PINS(J);
93
+    #endif
94
+    #ifdef PORTK
95
+      MAKE_AVR_PORT_PINS(K);
96
+    #endif
97
+    #ifdef PORTL
98
+      MAKE_AVR_PORT_PINS(L);
99
+    #endif
100
+    #ifdef PORTQ
101
+      MAKE_AVR_PORT_PINS(Q);
102
+    #endif
103
+    #ifdef PORTR
104
+      MAKE_AVR_PORT_PINS(R);
105
+    #endif
106
+
107
+    #undef MAKE_AVR_PORT_PINS
108
+
109
+    template<uint8_t p>
110
+    struct arduino_digital_pin {
111
+      static constexpr uint8_t pin = p;
112
+      static inline void set_high()          {digitalWrite(p, HIGH);}
113
+      static inline void set_low()           {digitalWrite(p, LOW);}
114
+      static inline void set_input()         {pinMode(p, INPUT);}
115
+      static inline void set_input_pullup()  {pinMode(p, INPUT_PULLUP);}
116
+      static inline void set_output()        {pinMode(p, OUTPUT);}
117
+      static inline uint8_t read()           {return digitalRead(p);}
118
+      static inline void write(bool v)       {digitalWrite(p, v ? HIGH : LOW);}
119
+    };
120
+
121
+    #define MAKE_ARDUINO_PINS(ID) typedef arduino_digital_pin<ID> ARDUINO_DIGITAL_##ID;
122
+    MAKE_ARDUINO_PINS( 0);
123
+    MAKE_ARDUINO_PINS( 1);
124
+    MAKE_ARDUINO_PINS( 2);
125
+    MAKE_ARDUINO_PINS( 3);
126
+    MAKE_ARDUINO_PINS( 4);
127
+    MAKE_ARDUINO_PINS( 5);
128
+    MAKE_ARDUINO_PINS( 6);
129
+    MAKE_ARDUINO_PINS( 7);
130
+    MAKE_ARDUINO_PINS( 8);
131
+    MAKE_ARDUINO_PINS( 9);
132
+    MAKE_ARDUINO_PINS(10);
133
+    MAKE_ARDUINO_PINS(11);
134
+    MAKE_ARDUINO_PINS(12);
135
+    MAKE_ARDUINO_PINS(13);
136
+    MAKE_ARDUINO_PINS(14);
137
+    MAKE_ARDUINO_PINS(15);
138
+    MAKE_ARDUINO_PINS(16);
139
+    MAKE_ARDUINO_PINS(17);
140
+    MAKE_ARDUINO_PINS(18);
141
+    MAKE_ARDUINO_PINS(19);
142
+    MAKE_ARDUINO_PINS(10);
143
+    MAKE_ARDUINO_PINS(21);
144
+    MAKE_ARDUINO_PINS(22);
145
+    MAKE_ARDUINO_PINS(23);
146
+    MAKE_ARDUINO_PINS(24);
147
+    MAKE_ARDUINO_PINS(25);
148
+    MAKE_ARDUINO_PINS(26);
149
+    MAKE_ARDUINO_PINS(27);
150
+    MAKE_ARDUINO_PINS(28);
151
+    MAKE_ARDUINO_PINS(29);
152
+    MAKE_ARDUINO_PINS(30);
153
+    MAKE_ARDUINO_PINS(31);
154
+    MAKE_ARDUINO_PINS(32);
155
+    MAKE_ARDUINO_PINS(33);
156
+    MAKE_ARDUINO_PINS(34);
157
+    MAKE_ARDUINO_PINS(35);
158
+    MAKE_ARDUINO_PINS(36);
159
+    MAKE_ARDUINO_PINS(37);
160
+    MAKE_ARDUINO_PINS(38);
161
+    MAKE_ARDUINO_PINS(39);
162
+    MAKE_ARDUINO_PINS(40);
163
+    MAKE_ARDUINO_PINS(41);
164
+    MAKE_ARDUINO_PINS(42);
165
+    MAKE_ARDUINO_PINS(43);
166
+    MAKE_ARDUINO_PINS(44);
167
+    MAKE_ARDUINO_PINS(45);
168
+    MAKE_ARDUINO_PINS(46);
169
+    MAKE_ARDUINO_PINS(47);
170
+    MAKE_ARDUINO_PINS(48);
171
+    MAKE_ARDUINO_PINS(49);
172
+    MAKE_ARDUINO_PINS(50);
173
+    MAKE_ARDUINO_PINS(51);
174
+    MAKE_ARDUINO_PINS(52);
175
+    MAKE_ARDUINO_PINS(53);
176
+    #undef MAKE_ARDUINO_PINS
177
+  } // namespace fast_io
178
+
179
+  #define SET_INPUT(pin)               fast_io::pin::set_input()
180
+  #define SET_INPUT_PULLUP(pin)        fast_io::pin::set_input(); fast_io::pin::set_high()
181
+  #define SET_OUTPUT(pin)              fast_io::pin::set_output()
182
+  #define READ(pin)                    fast_io::pin::read()
183
+  #define WRITE(pin, value)            fast_io::pin::write(value)
184
+
185
+  #ifndef pgm_read_word_far
186
+  #define pgm_read_word_far pgm_read_word
187
+  #endif
188
+
189
+  #ifndef pgm_read_dword_far
190
+  #define pgm_read_dword_far pgm_read_dword
191
+  #endif
192
+
193
+  #ifndef pgm_read_ptr_far
194
+  #define pgm_read_ptr_far pgm_read_ptr
195
+  #endif
196
+
197
+  #define SERIAL_ECHO_START()
198
+  #define SERIAL_ECHOLNPGM(str)        Serial.println(F(str))
199
+  #define SERIAL_ECHOPGM(str)          Serial.print(F(str))
200
+  #define SERIAL_ECHOLNPAIR(str, val) {Serial.print(F(str)); Serial.println(val);}
201
+  #define SERIAL_ECHOPAIR(str, val)   {Serial.print(F(str)); Serial.print(val);}
202
+
203
+  #define safe_delay delay
204
+
205
+  // Define macros for compatibility
206
+
207
+  #define _CAT(a, ...)       a ## __VA_ARGS__
208
+  #define SWITCH_ENABLED_    1
209
+  #define ENABLED(b)         _CAT(SWITCH_ENABLED_, b)
210
+  #define DISABLED(b)        !ENABLED(b)
211
+  #define ANY(A,B)           ENABLED(A) || ENABLED(B)
212
+
213
+  // Remove compiler warning on an unused variable
214
+  #ifndef UNUSED
215
+    #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
216
+      #define UNUSED(X) (void)X
217
+    #else
218
+      #define UNUSED(x) ((void)(x))
219
+    #endif
220
+  #endif
221
+
222
+#endif // !__MARLIN_FIRMWARE__

+ 49
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/bitmap_info.h View File

@@ -0,0 +1,49 @@
1
+/*****************
2
+ * bitmap_info.h *
3
+ *****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2019 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+#ifndef FORCEDINLINE
25
+  #define FORCEDINLINE __attribute__((always_inline)) inline
26
+#endif
27
+
28
+namespace FTDI {
29
+   // The following functions *must* be inlined since we are relying on the compiler to do
30
+   // substitution of the constants from the data structure rather than actually storing
31
+   // it in PROGMEM (which would fail, since we are not using pgm_read to read them).
32
+   // Plus, by inlining, all the equations are evaluated at compile-time as everything
33
+   // should be a constant.
34
+
35
+   typedef struct {
36
+     const uint8_t  format;
37
+     const uint16_t linestride;
38
+     const uint8_t  filter;
39
+     const uint8_t  wrapx;
40
+     const uint8_t  wrapy;
41
+     const uint32_t RAMG_offset;
42
+     const uint16_t width;
43
+     const uint16_t height;
44
+   } bitmap_info_t;
45
+
46
+   FORCEDINLINE uint32_t BITMAP_SOURCE (const bitmap_info_t& info) {return BITMAP_SOURCE (ftdi_memory_map::RAM_G + info.RAMG_offset);};
47
+   FORCEDINLINE uint32_t BITMAP_LAYOUT (const bitmap_info_t& info) {return BITMAP_LAYOUT (info.format, info.linestride, info.height);};
48
+   FORCEDINLINE uint32_t BITMAP_SIZE   (const bitmap_info_t& info) {return BITMAP_SIZE   (info.filter, info.wrapx, info.wrapy, info.width, info.height);}
49
+}

+ 29
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.cpp View File

@@ -0,0 +1,29 @@
1
+/*************************
2
+ * command_processor.cpp *
3
+ *************************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018                                        *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#include "ftdi_extended.h"
23
+
24
+#ifdef FTDI_EXTENDED
25
+
26
+CommandProcessor::btn_style_func_t  *CommandProcessor::_btn_style_callback = CommandProcessor::default_button_style_func;
27
+bool CommandProcessor::is_tracking = false;
28
+
29
+#endif // FTDI_EXTENDED

+ 347
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.h View File

@@ -0,0 +1,347 @@
1
+/***********************
2
+ * command_processor.h *
3
+ ***********************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+typedef struct {
25
+  uint32_t bg;
26
+  uint32_t grad;
27
+  uint32_t fg;
28
+  uint32_t rgb;
29
+} btn_colors;
30
+
31
+/**************************** Enhanced Command Processor **************************/
32
+
33
+/* The CommandProcessor class wraps the CommandFifo with several features to make
34
+ * defining user interfaces much easier.
35
+ *
36
+ *   - Implements chaining on all methods
37
+ *   - Automatically adds text to button, toggle, text and keys.
38
+ *   - Constrains all widgets to fit inside a box for ease of layout.
39
+ *   - Font size is specified using a chained modifier.
40
+ *   - Option argument is given the default OPT_3D value.
41
+ */
42
+
43
+class CommandProcessor : public CLCD::CommandFifo {
44
+  public:
45
+    static constexpr uint8_t STYLE_DISABLED = 0x80;
46
+
47
+  private:
48
+    static bool default_button_style_func(CommandProcessor &, uint8_t tag, uint8_t & /*style*/, uint16_t &options, bool) {
49
+      if (tag != 0 && FTDI::EventLoop::get_pressed_tag() == tag) {
50
+        options = FTDI::OPT_FLAT;
51
+      }
52
+      return false;
53
+    }
54
+
55
+    typedef bool btn_style_func_t(CommandProcessor &cmd, uint8_t tag, uint8_t &style, uint16_t &options, bool post);
56
+
57
+    static btn_style_func_t  *_btn_style_callback;
58
+    static bool is_tracking;
59
+    int8_t  _font = 26, _tag = 0;
60
+    uint8_t _style = 0;
61
+
62
+  protected:
63
+    // Returns the cannonical thickness of a widget (i.e. the height of a toggle element)
64
+    uint16_t widget_thickness() {
65
+      CLCD::FontMetrics fm(_font);
66
+      return fm.height * 20.0/16;
67
+    }
68
+
69
+    FORCEDINLINE void linear_widget_box(int16_t &x, int16_t &y, int16_t &w, int16_t &h, bool tracker = false) {
70
+      const uint16_t th = widget_thickness()/2;
71
+      if (w > h) {
72
+        x += tracker ? th * 2.5 : th;
73
+        y += h/2  - th/2;
74
+        w -= tracker ? th * 5.0 : th * 2;
75
+        h  = th;
76
+      } else {
77
+        x += w/2  - th/2;
78
+        y += tracker ? th * 2.5 : th;
79
+        w  = th;
80
+        h -= tracker ? th * 5.0 : th * 2;
81
+      }
82
+    }
83
+
84
+    FORCEDINLINE uint16_t circular_widget_box(int16_t &x, int16_t &y, int16_t &w, int16_t &h) {
85
+      const uint16_t r = min(w,h)/2;
86
+      x += w/2;
87
+      y += h/2;
88
+      w  = 1;
89
+      h  = 1;
90
+      return r;
91
+    }
92
+
93
+  public:
94
+    // Helper method for setting all colors at once
95
+    inline CommandProcessor& colors(const btn_colors &colors) {
96
+      cmd(FTDI::COLOR_RGB(colors.rgb))
97
+        .gradcolor(colors.grad)
98
+        .fgcolor(colors.fg)
99
+        .bgcolor(colors.bg);
100
+      return *this;
101
+    }
102
+
103
+    inline CommandProcessor& bitmap_size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) {
104
+      cmd(FTDI::BITMAP_SIZE(filter, wrapx, wrapy, width, height));
105
+      #if FTDI_API_LEVEL >= 810
106
+        if (FTDI::ftdi_chip >= 810)
107
+          cmd(FTDI::BITMAP_SIZE_H(width >> 9, height >> 9));
108
+      #endif
109
+      return *this;
110
+    }
111
+
112
+    inline CommandProcessor& bitmap_layout(uint8_t format, uint16_t linestride, uint16_t height) {
113
+      cmd(FTDI::BITMAP_LAYOUT(format, linestride, height));
114
+      #if FTDI_API_LEVEL >= 810
115
+        if (FTDI::ftdi_chip >= 810)
116
+          cmd(FTDI::BITMAP_LAYOUT_H(linestride >> 10, height >> 9));
117
+      #endif
118
+      return *this;
119
+    }
120
+
121
+    inline CommandProcessor& set_button_style_callback(const btn_style_func_t *func) {
122
+      _btn_style_callback = func ? func : default_button_style_func;
123
+      return *this;
124
+    }
125
+
126
+    inline CommandProcessor& tag      (uint8_t  tag)              {_tag = tag; cmd(FTDI::TAG(tag)); return *this;}
127
+
128
+    inline CommandProcessor& font     (int16_t  font)             {_font = font; return *this;}
129
+
130
+    inline CommandProcessor& enabled  (bool enabled) {
131
+      if (enabled)
132
+        _style &= ~STYLE_DISABLED;
133
+      else
134
+        _style |= STYLE_DISABLED;
135
+      return *this;
136
+    }
137
+
138
+    inline CommandProcessor& style    (uint8_t style) {
139
+      _style = (_style & STYLE_DISABLED) | style;
140
+      return *this;
141
+    }
142
+
143
+    // Wrap all the CommandFifo routines to allow method chaining
144
+
145
+    inline CommandProcessor& cmd      (uint32_t cmd32)            {CLCD::CommandFifo::cmd(cmd32); return *this;}
146
+    inline CommandProcessor& cmd      (void* data, uint16_t len)  {CLCD::CommandFifo::cmd(data, len); return *this;}
147
+    inline CommandProcessor& execute()                            {CLCD::CommandFifo::execute(); return *this;}
148
+
149
+    inline CommandProcessor& fgcolor  (uint32_t rgb)              {CLCD::CommandFifo::fgcolor(rgb); return *this;}
150
+    inline CommandProcessor& bgcolor  (uint32_t rgb)              {CLCD::CommandFifo::bgcolor(rgb); return *this;}
151
+    inline CommandProcessor& gradcolor(uint32_t rgb)              {CLCD::CommandFifo::gradcolor(rgb); return *this;}
152
+
153
+    inline CommandProcessor& snapshot (uint32_t ptr)              {CLCD::CommandFifo::snapshot(ptr); return *this;}
154
+
155
+    inline CommandProcessor& loadimage(uint32_t ptr, uint32_t options)
156
+                                                                  {CLCD::CommandFifo::loadimage(ptr, options); return *this;}
157
+    inline CommandProcessor& sketch   (int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format)
158
+                                                                  {CLCD::CommandFifo::sketch(x, y, w, h, ptr, format); return *this;}
159
+    inline CommandProcessor& screensaver  ()                      {CLCD::CommandFifo::screensaver(); return *this;}
160
+    #if FTDI_API_LEVEL >= 810
161
+    inline CommandProcessor& setbase  (uint8_t base)              {CLCD::CommandFifo::setbase(base); return *this;}
162
+    #endif
163
+    inline CommandProcessor& loadidentity ()                      {CLCD::CommandFifo::loadidentity(); return *this;}
164
+    inline CommandProcessor& scale    (int32_t sx, int32_t sy)    {CLCD::CommandFifo::scale(sx,sy); return *this;}
165
+    inline CommandProcessor& rotate   (int32_t a)                 {CLCD::CommandFifo::rotate(a); return *this;}
166
+    inline CommandProcessor& translate(int32_t tx, int32_t ty)    {CLCD::CommandFifo::translate(tx,ty); return *this;}
167
+    inline CommandProcessor& setmatrix ()                         {CLCD::CommandFifo::setmatrix(); return *this;}
168
+    inline CommandProcessor& stop ()                              {CLCD::CommandFifo::stop(); return *this;}
169
+
170
+    inline CommandProcessor& memzero  (uint32_t ptr, uint32_t size)
171
+                                                                  {CLCD::CommandFifo::memzero(ptr, size); return *this;}
172
+    inline CommandProcessor& memset   (uint32_t ptr, uint32_t val, uint32_t size)
173
+                                                                  {CLCD::CommandFifo::memset(ptr, val, size); return *this;}
174
+    inline CommandProcessor& memcpy   (uint32_t src, uint32_t dst, uint32_t size)
175
+                                                                  {CLCD::CommandFifo::memcpy(src, dst, size); return *this;}
176
+    inline CommandProcessor& memcrc   (uint32_t ptr, uint32_t num, uint32_t result)
177
+                                                                  {CLCD::CommandFifo::memcrc(ptr, num, result); return *this;}
178
+    inline CommandProcessor& memwrite (uint32_t ptr, uint32_t value)
179
+                                                                  {CLCD::CommandFifo::memwrite(ptr, value); return *this;}
180
+    inline CommandProcessor& inflate  (uint32_t ptr)
181
+                                                                  {CLCD::CommandFifo::inflate(ptr); return *this;}
182
+    inline CommandProcessor& getptr   (uint32_t result)
183
+                                                                  {CLCD::CommandFifo::getptr(result); return *this;}
184
+    inline CommandProcessor& getprops (uint32_t ptr, uint32_t width, uint32_t height)
185
+                                                                  {CLCD::CommandFifo::getprops(ptr, width, height); return *this;}
186
+
187
+    #if FTDI_API_LEVEL >= 810
188
+    inline CommandProcessor& setbitmap (uint32_t ptr, uint16_t fmt, uint16_t w, uint16_t h)
189
+                                                                  {CLCD::CommandFifo::setbitmap(ptr,fmt,w,h); return *this;}
190
+    inline CommandProcessor& snapshot2 (uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, uint16_t w, uint16_t h)
191
+                                                                  {CLCD::CommandFifo::snapshot2(fmt,ptr,x,y,w,h); return *this;}
192
+    inline CommandProcessor& mediafifo (uint32_t p, uint32_t s)   {CLCD::CommandFifo::mediafifo(p, s); return *this;}
193
+    inline CommandProcessor& playvideo(uint32_t options)          {CLCD::CommandFifo::playvideo(options); return *this;}
194
+    #endif
195
+
196
+    inline CommandProcessor& gradient(int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1)
197
+                                                                  {CLCD::CommandFifo::gradient(x0,y0,rgb0,x1,y1,rgb1); return *this;}
198
+
199
+    inline CommandProcessor& rectangle(int16_t x, int16_t y, int16_t w, int16_t h) {
200
+      using namespace FTDI;
201
+      CLCD::CommandFifo::cmd(BEGIN(RECTS));
202
+      CLCD::CommandFifo::cmd(VERTEX2F(x*16,y*16));
203
+      CLCD::CommandFifo::cmd(VERTEX2F((x+w)*16,(y+h)*16));
204
+      return *this;
205
+    }
206
+
207
+    template<typename T>
208
+    FORCEDINLINE CommandProcessor& toggle(int16_t x, int16_t y, int16_t w, int16_t h, T text, bool state, uint16_t options = FTDI::OPT_3D) {
209
+      CLCD::FontMetrics fm(_font);
210
+      const int16_t widget_h = fm.height * 20.0/16;
211
+      //const int16_t outer_bar_r = widget_h / 2;
212
+      //const int16_t knob_r      = outer_bar_r - 1.5;
213
+      // The y coordinate of the toggle is the baseline of the text,
214
+      // so we must introduce a fudge factor based on the line height to
215
+      // actually center the control.
216
+      const int16_t fudge_y = fm.height*5/16;
217
+      CLCD::CommandFifo::toggle(x + h/2, y + h/2 - widget_h/2 + fudge_y, w - h, _font, options, state);
218
+      CLCD::CommandFifo::str(text);
219
+      return *this;
220
+    }
221
+
222
+    // Contrained drawing routines. These constrain the widget inside a box for easier layout.
223
+    // The FORCEDINLINE ensures that the code is inlined so that all the math is done at compile time.
224
+
225
+    FORCEDINLINE CommandProcessor& track_linear(int16_t x, int16_t y, int16_t w, int16_t h, int16_t tag) {
226
+      linear_widget_box(x, y, w, h, true);
227
+      CLCD::CommandFifo::track(x, y, w, h, tag);
228
+      is_tracking = true;
229
+      return *this;
230
+    }
231
+
232
+    FORCEDINLINE CommandProcessor& track_circular(int16_t x, int16_t y, int16_t w, int16_t h, int16_t tag) {
233
+      circular_widget_box(x,y, w, h);
234
+      CLCD::CommandFifo::track(x, y, w, h, tag);
235
+      is_tracking = true;
236
+      return *this;
237
+    }
238
+
239
+    uint8_t track_tag (uint16_t &value) {
240
+      if (is_tracking) {
241
+        if (FTDI::EventLoop::is_touch_held()) {
242
+          return CLCD::get_tracker(value);
243
+        } else {
244
+          CLCD::CommandFifo::track(0, 0, 0, 0, 0);
245
+          CLCD::CommandFifo::execute();
246
+          is_tracking = false;
247
+        }
248
+      }
249
+      return 0;
250
+    }
251
+
252
+    FORCEDINLINE CommandProcessor& clock(int16_t x, int16_t y, int16_t w, int16_t h, int16_t hr, int16_t m, int16_t s, int16_t ms, uint16_t options = FTDI::OPT_3D) {
253
+      const uint16_t r = circular_widget_box(x, y, w, h);
254
+      CLCD::CommandFifo::clock(x, y, r, options, hr, m, s, ms);
255
+      return *this;
256
+    }
257
+
258
+    FORCEDINLINE CommandProcessor& gauge(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t major, uint16_t minor, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) {
259
+      const uint16_t r = circular_widget_box(x, y, w, h);
260
+      CLCD::CommandFifo::gauge(x, y, r, options, major, minor, val, range);
261
+      return *this;
262
+    }
263
+
264
+    FORCEDINLINE CommandProcessor& dial(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t options = FTDI::OPT_3D) {
265
+      const uint16_t r = circular_widget_box(x, y, w, h);
266
+      CLCD::CommandFifo::dial(x, y, r, options, val);
267
+      return *this;
268
+    }
269
+
270
+    FORCEDINLINE CommandProcessor& slider(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) {
271
+      linear_widget_box(x, y, w, h);
272
+      CLCD::CommandFifo::slider(x, y, w, h, options, val, range);
273
+      return *this;
274
+    }
275
+
276
+    FORCEDINLINE CommandProcessor& progress(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) {
277
+      linear_widget_box(x, y, w, h);
278
+      CLCD::CommandFifo::progress(x, y, w, h, options, val, range);
279
+      return *this;
280
+    }
281
+
282
+    FORCEDINLINE CommandProcessor& scrollbar(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t size, uint16_t range, uint16_t options = 0) {
283
+      linear_widget_box(x, y, w, h);
284
+      CLCD::CommandFifo::scrollbar(x, y, w, h, options, val, size, range);
285
+      return *this;
286
+    }
287
+
288
+    CommandProcessor& number(int16_t x, int16_t y, int16_t w, int16_t h, int32_t n, uint16_t options = FTDI::OPT_CENTER) {
289
+      using namespace FTDI;
290
+      CLCD::CommandFifo::number(
291
+        x + ((options & OPT_CENTERX) ? w/2 : ((options & OPT_RIGHTX) ? w : 0)),
292
+        y + ((options & OPT_CENTERY) ? h/2 : h),
293
+        _font, options, n);
294
+      return *this;
295
+    }
296
+
297
+    template<typename T> FORCEDINLINE
298
+    CommandProcessor& text(int16_t x, int16_t y, int16_t w, int16_t h, T text, uint16_t options = FTDI::OPT_CENTER) {
299
+      using namespace FTDI;
300
+      CLCD::CommandFifo::text(
301
+        x + ((options & OPT_CENTERX) ? w/2 : ((options & OPT_RIGHTX) ? w : 0)),
302
+        y + ((options & OPT_CENTERY) ? h/2 : h),
303
+        _font, options);
304
+      CLCD::CommandFifo::str(text);
305
+      return *this;
306
+    }
307
+
308
+    FORCEDINLINE CommandProcessor& icon(int16_t x, int16_t y, int16_t w, int16_t h, const FTDI::bitmap_info_t& info, const float scale = 1) {
309
+      using namespace FTDI;
310
+      cmd(BEGIN(BITMAPS));
311
+      if (scale != 1) {
312
+        cmd(BITMAP_TRANSFORM_A(uint32_t(float(256)/scale)));
313
+        cmd(BITMAP_TRANSFORM_E(uint32_t(float(256)/scale)));
314
+      }
315
+      cmd(BITMAP_SIZE(info.filter, info.wrapx, info.wrapy, info.width*scale, info.height*scale));
316
+      cmd(VERTEX2F((x + w/2 - info.width*scale/2)*16, (y + h/2 - info.height*scale/2)*16));
317
+      if (scale != 1) {
318
+        cmd(BITMAP_TRANSFORM_A(256));
319
+        cmd(BITMAP_TRANSFORM_E(256));
320
+      }
321
+      return *this;
322
+    }
323
+
324
+    template<typename T>
325
+    CommandProcessor& button(int16_t x, int16_t y, int16_t w, int16_t h, T text, uint16_t options = FTDI::OPT_3D) {
326
+      using namespace FTDI;
327
+      bool styleModified = false;
328
+      if (_btn_style_callback) styleModified = _btn_style_callback(*this, _tag, _style, options, false);
329
+      CLCD::CommandFifo::button(x, y, w, h, _font, options);
330
+      CLCD::CommandFifo::str(text);
331
+      if (_btn_style_callback && styleModified) _btn_style_callback(*this, _tag, _style, options, true);
332
+      return *this;
333
+    }
334
+
335
+    template<typename T>
336
+    CommandProcessor& keys(int16_t x, int16_t y, int16_t w, int16_t h, T keys, uint16_t options = FTDI::OPT_3D) {
337
+      CLCD::CommandFifo::keys(x, y, w, h, _font, options);
338
+      CLCD::CommandFifo::str(keys);
339
+      return *this;
340
+    }
341
+
342
+    FORCEDINLINE CommandProcessor& spinner(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t style = 0, uint16_t scale = 0) {
343
+      circular_widget_box(x, y, w, h);
344
+      CLCD::CommandFifo::spinner(x, y, style, scale);
345
+      return *this;
346
+    }
347
+};

+ 176
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.cpp View File

@@ -0,0 +1,176 @@
1
+/****************
2
+ * dl_cache.cpp *
3
+ ****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#include "ftdi_extended.h"
24
+
25
+#ifdef FTDI_EXTENDED
26
+
27
+/* The Display List Cache mechanism stores the display list corresponding
28
+ * to a menu into RAM_G so that on subsequent calls drawing the menu does
29
+ * not require as much SPI traffic.
30
+ *
31
+ * Layout of Cache memory:
32
+ *
33
+ * The cache memory begins with a table at
34
+ * DL_CACHE_START: each table entry contains
35
+ * an address and size for a cached DL slot.
36
+ *
37
+ * Immediately following the table is the
38
+ * DL_FREE_ADDR, which points to free cache
39
+ * space; following this is occupied DL space,
40
+ * and after that free space that is yet to
41
+ * be used.
42
+ *
43
+ *  location        data        sizeof
44
+ *
45
+ *  DL_CACHE_START  slot0_addr     4
46
+ *                  slot0_size     4
47
+ *                  slot1_addr     4
48
+ *                  slot1_size     4
49
+ *                      ...
50
+ *                  slotN_addr     4
51
+ *                  slotN_size     4
52
+ *  DL_FREE_ADDR    dl_free_ptr    4
53
+ *                  cached data
54
+ *                      ...
55
+ *  dl_free_ptr     empty space
56
+ *                      ...
57
+ */
58
+
59
+#define DL_CACHE_START   MAP::RAM_G_SIZE - 0xFFFF
60
+#define DL_FREE_ADDR     DL_CACHE_START + DL_CACHE_SLOTS * 8
61
+
62
+using namespace FTDI;
63
+
64
+// The init function ensures all cache locations are marked as empty
65
+
66
+void DLCache::init() {
67
+  CLCD::mem_write_32(DL_FREE_ADDR, DL_FREE_ADDR + 4);
68
+  for(uint8_t slot = 0; slot < DL_CACHE_SLOTS; slot++) {
69
+    save_slot(slot, 0, 0);
70
+  }
71
+}
72
+
73
+bool DLCache::has_data() {
74
+  return dl_size != 0;
75
+}
76
+
77
+bool DLCache::wait_until_idle() {
78
+  const unsigned long startTime = millis();
79
+  do {
80
+    if ((millis() - startTime) > 250) {
81
+      SERIAL_ECHO_START();
82
+      SERIAL_ECHOLNPGM("Timeout on DL_Cache::Wait_Until_Idle()");
83
+      CLCD::CommandFifo::reset();
84
+      return false;
85
+    }
86
+    #ifdef __MARLIN_FIRMWARE__
87
+      ExtUI::yield();
88
+    #endif
89
+  } while (CLCD::CommandFifo::is_processing());
90
+  return true;
91
+}
92
+
93
+/* This caches the current display list in RAMG so
94
+ * that it can be appended later. The memory is
95
+ * dynamically allocated following DL_FREE_ADDR.
96
+ *
97
+ * If num_bytes is provided, then that many bytes
98
+ * will be reserved so that the cache may be re-written
99
+ * later with potentially a bigger DL.
100
+ */
101
+
102
+bool DLCache::store(uint32_t num_bytes /* = 0*/) {
103
+  CLCD::CommandFifo cmd;
104
+
105
+  // Execute any commands already in the FIFO
106
+  cmd.execute();
107
+  if (!wait_until_idle())
108
+    return false;
109
+
110
+  // Figure out how long the display list is
111
+  uint32_t new_dl_size = CLCD::mem_read_32(REG::CMD_DL) & 0x1FFF;
112
+  uint32_t free_space  = 0;
113
+  uint32_t dl_alloc    = 0;
114
+
115
+  if (dl_addr == 0) {
116
+    // If we are allocating new space...
117
+    dl_addr     = CLCD::mem_read_32(DL_FREE_ADDR);
118
+    free_space  = MAP::RAM_G_SIZE - dl_addr;
119
+    dl_alloc    = num_bytes ? num_bytes : new_dl_size;
120
+    dl_size     = new_dl_size;
121
+  } else {
122
+    // Otherwise, we can only store as much space
123
+    // as was previously allocated.
124
+    free_space  = num_bytes ? num_bytes : dl_size;
125
+    dl_alloc    = 0;
126
+    dl_size     = new_dl_size;
127
+  }
128
+
129
+  if (dl_size > free_space) {
130
+    // Not enough memory to cache the display list.
131
+    #ifdef UI_FRAMEWORK_DEBUG
132
+      SERIAL_ECHO_START();
133
+      SERIAL_ECHOPAIR("Not enough space in GRAM to cache display list, free space: ", free_space);
134
+      SERIAL_ECHOLNPAIR(" Required: ", dl_size);
135
+    #endif
136
+    return false;
137
+  } else {
138
+    #ifdef UI_FRAMEWORK_DEBUG
139
+      SERIAL_ECHO_START();
140
+      SERIAL_ECHOPAIR("Saving DL to RAMG cache, bytes: ", dl_size);
141
+      SERIAL_ECHOLNPAIR(" Free space: ", free_space);
142
+    #endif
143
+    cmd.memcpy(dl_addr, MAP::RAM_DL, dl_size);
144
+    cmd.execute();
145
+    save_slot(dl_slot, dl_addr, dl_size);
146
+    if (dl_alloc > 0) {
147
+      // If we allocated space dynamically, then adjust dl_free_addr.
148
+      CLCD::mem_write_32(DL_FREE_ADDR, dl_addr + dl_alloc);
149
+    }
150
+    return true;
151
+  }
152
+}
153
+
154
+void DLCache::save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size) {
155
+  CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 0, dl_addr);
156
+  CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 4, dl_size);
157
+}
158
+
159
+void DLCache::load_slot() {
160
+  dl_addr  = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 0);
161
+  dl_size  = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 4);
162
+}
163
+
164
+void DLCache::append() {
165
+  CLCD::CommandFifo cmd;
166
+  cmd.append(dl_addr, dl_size);
167
+  #ifdef UI_FRAMEWORK_DEBUG
168
+    cmd.execute();
169
+    wait_until_idle();
170
+    SERIAL_ECHO_START();
171
+    SERIAL_ECHOPAIR("Appending to DL from RAMG cache, bytes: ", dl_size);
172
+    SERIAL_ECHOLNPAIR(" REG_CMD_DL: ", CLCD::mem_read_32(REG::CMD_DL));
173
+  #endif
174
+}
175
+
176
+#endif // FTDI_EXTENDED

+ 69
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.h View File

@@ -0,0 +1,69 @@
1
+/**************
2
+ * dl_cache.h *
3
+ **************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+/******************* DISPLAY LIST CACHE MANAGEMENT ************************/
25
+/* The Display List Cache mechanism stores the display list corresponding
26
+ * to a menu into RAM_G so that on subsequent calls drawing the menu does
27
+ * not require as much SPI traffic. Dynamic content, such as indicators,
28
+ * should not be cached.
29
+ *
30
+ * The DLCache can be used like so:
31
+ *
32
+ *   void some_function() {
33
+ *     DLCache dlcache(UNIQUE_ID);
34
+ *
35
+ *     if (dlcache.hasData()) {
36
+ *        dlcache.append();
37
+ *     } else {
38
+ *        // Add stuff to the DL
39
+ *        dlcache.store();
40
+ *     }
41
+ */
42
+class DLCache {
43
+  private:
44
+    typedef FTDI::ftdi_registers  REG;
45
+    typedef FTDI::ftdi_memory_map MAP;
46
+
47
+    uint8_t  dl_slot;
48
+    uint32_t dl_addr;
49
+    uint16_t dl_size;
50
+
51
+    void load_slot();
52
+    static void save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size);
53
+
54
+    bool wait_until_idle();
55
+
56
+  public:
57
+    static void init();
58
+
59
+    DLCache(uint8_t slot) {
60
+      dl_slot = slot;
61
+      load_slot();
62
+    }
63
+
64
+    bool has_data();
65
+    bool store(uint32_t num_bytes = 0);
66
+    void append();
67
+};
68
+
69
+#define DL_CACHE_SLOTS   250

+ 230
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.cpp View File

@@ -0,0 +1,230 @@
1
+/******************
2
+ * event_loop.cpp *
3
+ ******************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#include "ftdi_extended.h"
24
+
25
+#ifdef FTDI_EXTENDED
26
+using namespace FTDI;
27
+
28
+enum {
29
+  UNPRESSED       = 0x00
30
+};
31
+
32
+tiny_timer_t touch_timer;
33
+UIData::flags_t UIData::flags;
34
+uint8_t pressed_tag  = UNPRESSED;
35
+
36
+uint8_t UIData::get_persistent_data_mask() {
37
+  // A bit mask for flags that should be stored to the EEPROM.
38
+  // Others are considered temporarily values that need not be
39
+  // saved.
40
+  constexpr flags_t persistent_flags = {
41
+    bits: {
42
+      touch_start_sound:  true,
43
+      touch_end_sound:    true,
44
+      touch_repeat_sound: true,
45
+      show_animations:    true
46
+    }
47
+  };
48
+  return persistent_flags.value;
49
+}
50
+
51
+void UIData::reset_persistent_data() {
52
+  // Default values for persistent data
53
+  constexpr flags_t default_flags = {
54
+    bits: {
55
+      touch_start_sound:  true,
56
+      touch_end_sound:    true,
57
+      touch_repeat_sound: true,
58
+      show_animations:    true,
59
+      touch_debouncing:   false,
60
+      ignore_unpress:     false
61
+    }
62
+  };
63
+  flags.value = default_flags.value;
64
+}
65
+
66
+uint8_t UIData::get_persistent_data() {
67
+  return flags.value & get_persistent_data_mask();
68
+}
69
+
70
+void UIData::set_persistent_data(uint8_t value) {
71
+  flags.value = value & get_persistent_data_mask();
72
+}
73
+
74
+
75
+void UIData::enable_touch_sounds(bool enabled) {
76
+  UIData::flags.bits.touch_start_sound  = enabled;
77
+  UIData::flags.bits.touch_end_sound    = enabled;
78
+  UIData::flags.bits.touch_repeat_sound = enabled;
79
+}
80
+
81
+bool UIData::touch_sounds_enabled() {
82
+  return UIData::flags.bits.touch_start_sound || UIData::flags.bits.touch_end_sound || UIData::flags.bits.touch_repeat_sound;
83
+}
84
+
85
+void UIData::enable_animations(bool enabled) {
86
+    UIData::flags.bits.show_animations = enabled;
87
+}
88
+
89
+bool UIData::animations_enabled() {
90
+  return UIData::flags.bits.show_animations;
91
+}
92
+
93
+namespace FTDI {
94
+  uint8_t EventLoop::get_pressed_tag() {
95
+    return pressed_tag;
96
+  }
97
+
98
+  bool EventLoop::is_touch_held() {
99
+    return pressed_tag != 0;
100
+  }
101
+
102
+  /**
103
+   * process_events(): Process events from the touch panel.
104
+   *
105
+   * This function consists of a state machine that accomplishes the following:
106
+   *
107
+   *  - Reads the tag register from the touch panel
108
+   *  - Dispatches onTouchStart and onTouchEnd events to the active screen.
109
+   *  - Handles auto-repetition by sending onTouchHeld to the active screen periodically.
110
+   *  - Plays touch feedback "click" sounds when appropriate.
111
+   *  - Performs debouncing to supress spurious touch events.
112
+   *
113
+   */
114
+  void EventLoop::process_events() {
115
+    // If the LCD is processing commands, don't check
116
+    // for tags since they may be changing and could
117
+    // cause spurious events.
118
+    if (!touch_timer.elapsed(TOUCH_UPDATE_INTERVAL) || CLCD::CommandFifo::is_processing()) {
119
+      return;
120
+    }
121
+
122
+    const uint8_t tag = CLCD::get_tag();
123
+
124
+    switch (pressed_tag) {
125
+      case UNPRESSED:
126
+        if (tag != 0) {
127
+          #ifdef UI_FRAMEWORK_DEBUG
128
+            SERIAL_ECHO_START();
129
+            SERIAL_ECHOLNPAIR("Touch start: ", tag);
130
+          #endif
131
+
132
+          pressed_tag = tag;
133
+          current_screen.onRefresh();
134
+
135
+          // When the user taps on a button, activate the onTouchStart handler
136
+          const uint8_t lastScreen = current_screen.getScreen();
137
+
138
+          if (current_screen.onTouchStart(tag)) {
139
+            touch_timer.start();
140
+            if (UIData::flags.bits.touch_start_sound) sound.play(press_sound);
141
+          }
142
+
143
+          if (lastScreen != current_screen.getScreen()) {
144
+            // In the case in which a touch event triggered a new screen to be
145
+            // drawn, we don't issue a touchEnd since it would be sent to the
146
+            // wrong screen.
147
+            UIData::flags.bits.ignore_unpress = true;
148
+          } else {
149
+            UIData::flags.bits.ignore_unpress = false;
150
+          }
151
+        } else {
152
+          touch_timer.start();
153
+        }
154
+        break;
155
+      default: // PRESSED
156
+        if (!UIData::flags.bits.touch_debouncing) {
157
+          if (tag == pressed_tag) {
158
+            // The user is holding down a button.
159
+            if (touch_timer.elapsed(1000 / TOUCH_REPEATS_PER_SECOND) && current_screen.onTouchHeld(tag)) {
160
+              current_screen.onRefresh();
161
+              if (UIData::flags.bits.touch_repeat_sound) sound.play(repeat_sound);
162
+              touch_timer.start();
163
+            }
164
+          }
165
+          else if (tag == 0) {
166
+            touch_timer.start();
167
+            UIData::flags.bits.touch_debouncing = true;
168
+          }
169
+        }
170
+
171
+        else {
172
+          // Debouncing...
173
+
174
+          if (tag == pressed_tag) {
175
+            // If while debouncing, we detect a press, then cancel debouncing.
176
+            UIData::flags.bits.touch_debouncing = false;
177
+          }
178
+
179
+          else if (touch_timer.elapsed(DEBOUNCE_PERIOD)) {
180
+            UIData::flags.bits.touch_debouncing = false;
181
+
182
+            if (UIData::flags.bits.ignore_unpress) {
183
+              UIData::flags.bits.ignore_unpress = false;
184
+              pressed_tag = UNPRESSED;
185
+              break;
186
+            }
187
+
188
+            if (UIData::flags.bits.touch_end_sound) sound.play(unpress_sound);
189
+
190
+            #ifdef UI_FRAMEWORK_DEBUG
191
+              SERIAL_ECHO_START();
192
+              SERIAL_ECHOLNPAIR("Touch end: ", tag);
193
+            #endif
194
+
195
+            const uint8_t saved_pressed_tag = pressed_tag;
196
+            pressed_tag = UNPRESSED;
197
+            current_screen.onTouchEnd(saved_pressed_tag);
198
+            current_screen.onRefresh();
199
+          }
200
+        }
201
+        break;
202
+    } // switch (pressed_tag)
203
+
204
+  } // processEvents()
205
+
206
+  void EventLoop::setup() {
207
+    CLCD::init();
208
+    DLCache::init();
209
+    UIData::reset_persistent_data();
210
+    current_screen.start();
211
+  }
212
+
213
+  void EventLoop::loop() {
214
+    sound.onIdle();
215
+
216
+    /**
217
+      * Guard against re-entry of UI methods, which can
218
+      * crash. Re-entry can happen because some functions
219
+      * (e.g. planner.synchronize) call idle().
220
+      */
221
+    if (!UIData::flags.bits.prevent_reentry) {
222
+      UIData::flags.bits.prevent_reentry = true;
223
+      current_screen.onIdle();
224
+      process_events();
225
+      UIData::flags.bits.prevent_reentry = false;
226
+    }
227
+  }
228
+} // namespace FTDI
229
+
230
+#endif // FTDI_EXTENDED

+ 74
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.h View File

@@ -0,0 +1,74 @@
1
+/****************
2
+ * event_loop.h *
3
+ ****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+#define STATUS_UPDATE_INTERVAL     1000
26
+#define TOUCH_UPDATE_INTERVAL        50
27
+#define TOUCH_REPEATS_PER_SECOND      4
28
+#define DEBOUNCE_PERIOD             150
29
+
30
+class UIData {
31
+  private:
32
+    typedef union {
33
+      struct {
34
+        uint8_t touch_start_sound  : 1;
35
+        uint8_t touch_end_sound    : 1;
36
+        uint8_t touch_repeat_sound : 1;
37
+        uint8_t show_animations    : 1;
38
+        uint8_t touch_debouncing   : 1;
39
+        uint8_t ignore_unpress     : 1;
40
+        uint8_t prevent_reentry    : 1;
41
+      } bits;
42
+      uint8_t value;
43
+    } flags_t;
44
+
45
+  public:
46
+    static flags_t flags;
47
+
48
+    static uint8_t get_persistent_data_mask();
49
+    static uint8_t get_persistent_data();
50
+    static void set_persistent_data(uint8_t value);
51
+    static void reset_persistent_data();
52
+
53
+    static void enable_touch_sounds(bool enabled);
54
+    static bool touch_sounds_enabled();
55
+    static void enable_animations(bool enabled);
56
+    static bool animations_enabled();
57
+};
58
+
59
+namespace FTDI {
60
+  class EventLoop {
61
+    private:
62
+      static constexpr FTDI::effect_t press_sound   = FTDI::CHACK;
63
+      static constexpr FTDI::effect_t repeat_sound  = FTDI::CHACK;
64
+      static constexpr FTDI::effect_t unpress_sound = FTDI::POP;
65
+      static void process_events();
66
+
67
+    public:
68
+      static void setup();
69
+      static void loop();
70
+
71
+      static uint8_t get_pressed_tag();
72
+      static bool is_touch_held();
73
+  };
74
+}

+ 45
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/ftdi_extended.h View File

@@ -0,0 +1,45 @@
1
+/*******************
2
+ * ftdi_extended.h *
3
+ *******************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2019 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 201( - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+#include "../compat.h"
26
+#include "../basic/ftdi_basic.h"
27
+
28
+#if !defined(__MARLIN_FIRMWARE__)
29
+  #define FTDI_EXTENDED
30
+#endif
31
+
32
+#ifdef FTDI_EXTENDED
33
+  #include "rgb_t.h"
34
+  #include "bitmap_info.h"
35
+  #include "tiny_timer.h"
36
+  #include "grid_layout.h"
37
+  #include "dl_cache.h"
38
+  #include "screen_types.h"
39
+  #include "event_loop.h"
40
+  #include "command_processor.h"
41
+  #include "sound_player.h"
42
+  #include "sound_list.h"
43
+  #include "polygon.h"
44
+  #include "text_box.h"
45
+#endif

+ 98
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/grid_layout.h View File

@@ -0,0 +1,98 @@
1
+/*****************
2
+ * grid_layout.h *
3
+ *****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+/* The grid layout macros allow buttons to be arranged on a grid so
25
+ * that their locations become independent of the display size. The
26
+ * layout model is similar to that of HTML TABLEs.
27
+ *
28
+ * These macros are meant to be evaluated into constants at compile
29
+ * time, so resolution independence can be as efficient as using
30
+ * hard-coded coordinates.
31
+ */
32
+
33
+// Margin defines the margin (in pixels) on each side of a button in
34
+// the layout
35
+
36
+#ifdef TOUCH_UI_800x480
37
+  #define MARGIN_L         5
38
+  #define MARGIN_R         5
39
+  #define MARGIN_T         5
40
+  #define MARGIN_B         5
41
+  #define MARGIN_DEFAULT   5
42
+#else
43
+  #define MARGIN_L         3
44
+  #define MARGIN_R         3
45
+  #define MARGIN_T         3
46
+  #define MARGIN_B         3
47
+  #define MARGIN_DEFAULT   3
48
+#endif
49
+
50
+// EDGE_R adds some black space on the right edge of the display
51
+// This shifts some of the screens left to visually center them.
52
+
53
+#define EDGE_R           0
54
+
55
+// GRID_X and GRID_Y computes the positions of the divisions on
56
+// the layout grid.
57
+#define GRID_X(x)        ((x)*(FTDI::display_width-EDGE_R)/GRID_COLS)
58
+#define GRID_Y(y)        ((y)*FTDI::display_height/GRID_ROWS)
59
+
60
+// BTN_X, BTN_Y, BTN_W and BTN_X returns the top-left and width
61
+// and height of a button, taking into account the button margins.
62
+
63
+#define BTN_X(x)         (GRID_X((x)-1) + MARGIN_L)
64
+#define BTN_Y(y)         (GRID_Y((y)-1) + MARGIN_T)
65
+#define BTN_W(w)         (GRID_X(w)   - MARGIN_L - MARGIN_R)
66
+#define BTN_H(h)         (GRID_Y(h)   - MARGIN_T - MARGIN_B)
67
+
68
+// Abbreviations for common phrases, to allow a button to be
69
+// defined in one line of source.
70
+#define BTN_POS(x,y)     BTN_X(x), BTN_Y(y)
71
+#define BTN_SIZE(w,h)    BTN_W(w), BTN_H(h)
72
+
73
+// Draw a reference grid for ease of spacing out widgets.
74
+#define DRAW_LAYOUT_GRID \
75
+  { \
76
+    cmd.cmd(LINE_WIDTH(4)); \
77
+    for(int i = 1; i <= GRID_COLS; i++) { \
78
+      cmd.cmd(BEGIN(LINES)); \
79
+      cmd.cmd(VERTEX2F(GRID_X(i) *16, 0             *16)); \
80
+      cmd.cmd(VERTEX2F(GRID_X(i) *16, FTDI::display_height *16)); \
81
+    } \
82
+    for(int i = 1; i < GRID_ROWS; i++) { \
83
+      cmd.cmd(BEGIN(LINES)); \
84
+      cmd.cmd(VERTEX2F(0                       *16, GRID_Y(i) *16)); \
85
+      cmd.cmd(VERTEX2F(FTDI::display_width     *16, GRID_Y(i) *16)); \
86
+    } \
87
+    cmd.cmd(LINE_WIDTH(16)); \
88
+  }
89
+
90
+namespace FTDI {
91
+  #ifdef TOUCH_UI_PORTRAIT
92
+    constexpr uint16_t display_width  = Vsize;
93
+    constexpr uint16_t display_height = Hsize;
94
+  #else
95
+    constexpr uint16_t display_width  = Hsize;
96
+    constexpr uint16_t display_height = Vsize;
97
+  #endif
98
+}

+ 96
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/polygon.h View File

@@ -0,0 +1,96 @@
1
+/*************
2
+ * polygon.h *
3
+ *************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2019 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+/**
25
+ * The Polygon class helps drawing filled or stroked polygons on the FTDI EVE:
26
+ *
27
+ *   CommandProcessor cmd;
28
+ *   cmd.cmd(COLOR_RGB(0x00FF00));
29
+ *
30
+ *   Polygon p(cmd);
31
+ *   p.begin_fill();
32
+ *     p.begin_loop();
33
+ *      p(10,10);
34
+ *      p(20,10);
35
+ *      p(20,20);
36
+ *      p(10,20);
37
+ *     p.end_loop();
38
+ *     p.begin_loop();
39
+ *        ...  // Additional closed paths
40
+ *     p.end_loop();
41
+ *        ...
42
+ *   p.end_fill();
43
+ *
44
+ * Based on the example from "Applicaton Note AN_334, FT801 Polygon Application":
45
+ *
46
+ *   https://brtchip.com/wp-content/uploads/Support/Documentation/Application_Notes/ICs/EVE/AN_334-FT801_Polygon_Application.pdf
47
+ */
48
+
49
+namespace FTDI {
50
+  class Polygon {
51
+    private:
52
+      FTDI::begin_t path_initiator = FTDI::LINE_STRIP;
53
+
54
+    public:
55
+      CommandProcessor &cmd;
56
+
57
+      Polygon(CommandProcessor &c) : cmd(c) {}
58
+
59
+      void begin_fill() {
60
+        using namespace FTDI;
61
+        cmd.cmd(SAVE_CONTEXT());
62
+        cmd.cmd(TAG_MASK(0));
63
+        cmd.cmd(CLEAR(0,1,0));
64
+        cmd.cmd(COLOR_MASK(0,0,0,0));
65
+        cmd.cmd(STENCIL_OP(STENCIL_OP_KEEP, STENCIL_OP_INVERT));
66
+        cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_ALWAYS, 255, 255));
67
+        // Drawing the edge strip along scan lines
68
+        // seems to yield the best performance
69
+        #ifdef TOUCH_UI_PORTRAIT
70
+          path_initiator = EDGE_STRIP_B;
71
+        #else
72
+          path_initiator = EDGE_STRIP_R;
73
+        #endif
74
+      }
75
+
76
+      // Specify a clipping rectangle to paint fewer pixels and reduce rendering time, otherwise all pixels will be painted.
77
+      void end_fill(const int16_t x1 = 0, const int16_t y1 = 0, const int16_t x2 = display_width * 16, const int16_t y2 = display_height * 16) {
78
+        using namespace FTDI;
79
+        cmd.cmd(RESTORE_CONTEXT());
80
+
81
+        cmd.cmd(SAVE_CONTEXT());
82
+        cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_NOTEQUAL, 0, 255));
83
+        cmd.cmd(BEGIN(RECTS));
84
+        cmd.cmd(VERTEX2F(x1, y1));
85
+        cmd.cmd(VERTEX2F(x2, y2));
86
+        cmd.cmd(RESTORE_CONTEXT());
87
+      }
88
+
89
+      void begin_stroke() {path_initiator = FTDI::LINE_STRIP;}
90
+      void begin_loop()   {cmd.cmd(FTDI::BEGIN(path_initiator));}
91
+      void end_stroke()   {}
92
+      void end_loop()     {}
93
+
94
+      void operator()(const uint16_t x, const uint16_t y) {cmd.cmd(FTDI::VERTEX2F(x, y));}
95
+  };
96
+}

+ 44
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/rgb_t.h View File

@@ -0,0 +1,44 @@
1
+/***********
2
+ * rgb_t.h *
3
+ ***********/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+struct rgb_t {
25
+    union {
26
+      struct {
27
+        uint8_t  b,g,r,a;
28
+      };
29
+      uint32_t packed;
30
+    };
31
+
32
+    rgb_t()                                : packed(0)              {}
33
+    rgb_t(uint32_t rgb)                    : packed(rgb)            {}
34
+    rgb_t(uint8_t r, uint8_t g, uint8_t b) : b(b), g(g), r(r), a(0) {}
35
+    operator uint32_t() const              {return packed;};
36
+
37
+    static void lerp(float t, const rgb_t a, const rgb_t b, rgb_t &c) {
38
+      c.r = a.r + t * (b.r - a.r);
39
+      c.g = a.g + t * (b.g - a.g);
40
+      c.b = a.b + t * (b.b - a.b);
41
+    }
42
+
43
+    uint8_t luminance() const {return 0.299*r + 0.587*g + 0.114*b;}
44
+};

+ 106
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.cpp View File

@@ -0,0 +1,106 @@
1
+/******************
2
+ * screen_types.h *
3
+ ******************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#include "ftdi_extended.h"
23
+
24
+#ifdef FTDI_EXTENDED
25
+
26
+/********************** VIRTUAL DISPATCH DATA TYPE  ******************************/
27
+
28
+uint8_t ScreenRef::lookupScreen(onRedraw_func_t onRedraw_ptr) {
29
+  for(uint8_t type = 0; type < functionTableSize; type++) {
30
+    if (GET_METHOD(type, onRedraw) == onRedraw_ptr) {
31
+      return type;
32
+    }
33
+  }
34
+  #ifdef UI_FRAMEWORK_DEBUG
35
+    SERIAL_ECHO_START();
36
+    SERIAL_ECHOPAIR("Screen not found: ", (uintptr_t) onRedraw_ptr);
37
+  #endif
38
+  return 0xFF;
39
+}
40
+
41
+void ScreenRef::setScreen(onRedraw_func_t onRedraw_ptr) {
42
+  uint8_t type = lookupScreen(onRedraw_ptr);
43
+  if (type != 0xFF) {
44
+    setType(type);
45
+    #ifdef UI_FRAMEWORK_DEBUG
46
+      SERIAL_ECHO_START();
47
+      SERIAL_ECHOLNPAIR("New screen: ", type);
48
+    #endif
49
+  }
50
+}
51
+
52
+void ScreenRef::initializeAll() {
53
+  for(uint8_t type = 0; type < functionTableSize; type++) {
54
+    GET_METHOD(type, onStartup)();
55
+  }
56
+}
57
+
58
+/********************** SCREEN STACK  ******************************/
59
+
60
+void ScreenStack::start() {
61
+  initializeAll();
62
+  onEntry();
63
+}
64
+
65
+void ScreenStack::push(onRedraw_func_t onRedraw_ptr) {
66
+  stack[3] = stack[2];
67
+  stack[2] = stack[1];
68
+  stack[1] = stack[0];
69
+  stack[0] = lookupScreen(onRedraw_ptr);
70
+}
71
+
72
+void ScreenStack::push() {
73
+  stack[3] = stack[2];
74
+  stack[2] = stack[1];
75
+  stack[1] = stack[0];
76
+  stack[0] = getType();
77
+}
78
+
79
+void ScreenStack::pop() {
80
+  setType(stack[0]);
81
+  forget();
82
+}
83
+
84
+void ScreenStack::forget() {
85
+  stack[0] = stack[1];
86
+  stack[1] = stack[2];
87
+  stack[2] = stack[3];
88
+  stack[3] = 0;
89
+}
90
+
91
+void ScreenStack::goTo(onRedraw_func_t s) {
92
+  push();
93
+  onExit();
94
+  setScreen(s);
95
+  onEntry();
96
+}
97
+
98
+void ScreenStack::goBack() {
99
+  onExit();
100
+  pop();
101
+  onEntry();
102
+}
103
+
104
+ScreenStack current_screen;
105
+
106
+#endif // FTDI_EXTENDED

+ 215
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.h View File

@@ -0,0 +1,215 @@
1
+/********************
2
+ * screen_types.cpp *
3
+ ********************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+typedef enum {
25
+  BACKGROUND  = 1,
26
+  FOREGROUND  = 2,
27
+  BOTH        = 3
28
+} draw_mode_t;
29
+
30
+ /********************** VIRTUAL DISPATCH DATA TYPE  ******************************/
31
+
32
+// True virtual classes are extremely expensive on the Arduino
33
+// as the compiler stores the virtual function tables in RAM.
34
+// We invent a data type called ScreenRef that gives us
35
+// polymorphism by mapping an ID to virtual methods on various
36
+// classes. This works by keeping a table in PROGMEM of pointers
37
+// to static methods.
38
+
39
+#define DECL_SCREEN(className) { \
40
+  className::onStartup, \
41
+  className::onEntry, \
42
+  className::onExit, \
43
+  className::onIdle, \
44
+  className::onRefresh, \
45
+  className::onRedraw, \
46
+  className::onTouchStart, \
47
+  className::onTouchHeld, \
48
+  className::onTouchEnd \
49
+}
50
+
51
+#define GET_METHOD(type, method) reinterpret_cast<method##_func_t*>(pgm_read_ptr_far(&functionTable[type].method##_ptr))
52
+#define SCREEN_TABLE             PROGMEM const ScreenRef::table_t ScreenRef::functionTable[] =
53
+#define SCREEN_TABLE_POST        const uint8_t ScreenRef::functionTableSize = sizeof(ScreenRef::functionTable)/sizeof(ScreenRef::functionTable[0]);
54
+
55
+class ScreenRef {
56
+  protected:
57
+    typedef void onStartup_func_t(void);
58
+    typedef void onEntry_func_t(void);
59
+    typedef void onExit_func_t(void);
60
+    typedef void onIdle_func_t(void);
61
+    typedef void onRefresh_func_t(void);
62
+    typedef void onRedraw_func_t(draw_mode_t);
63
+    typedef bool onTouchStart_func_t(uint8_t);
64
+    typedef bool onTouchHeld_func_t(uint8_t);
65
+    typedef bool onTouchEnd_func_t(uint8_t);
66
+
67
+  private:
68
+    typedef struct {
69
+      onStartup_func_t     *onStartup_ptr;
70
+      onEntry_func_t       *onEntry_ptr;
71
+      onExit_func_t        *onExit_ptr;
72
+      onIdle_func_t        *onIdle_ptr;
73
+      onRefresh_func_t     *onRefresh_ptr;
74
+      onRedraw_func_t      *onRedraw_ptr;
75
+      onTouchStart_func_t  *onTouchStart_ptr;
76
+      onTouchHeld_func_t   *onTouchHeld_ptr;
77
+      onTouchEnd_func_t    *onTouchEnd_ptr;
78
+    } table_t;
79
+
80
+    uint8_t type = 0;
81
+    static PROGMEM const table_t functionTable[];
82
+    static const uint8_t functionTableSize;
83
+
84
+  public:
85
+    uint8_t getType() {return type;}
86
+
87
+    void setType(uint8_t t) {
88
+      type = t;
89
+    }
90
+
91
+    uint8_t lookupScreen(onRedraw_func_t onRedraw_ptr);
92
+
93
+    void setScreen(onRedraw_func_t onRedraw_ptr);
94
+
95
+    void onStartup()               {GET_METHOD(type, onStartup)();}
96
+    void onEntry()                 {GET_METHOD(type, onEntry)();}
97
+    void onExit()                  {GET_METHOD(type, onExit)();}
98
+    void onIdle()                  {GET_METHOD(type, onIdle)();}
99
+    void onRefresh()               {GET_METHOD(type, onRefresh)();}
100
+    void onRedraw(draw_mode_t dm)  {GET_METHOD(type, onRedraw)(dm);}
101
+    bool onTouchStart(uint8_t tag) {return GET_METHOD(type, onTouchStart)(tag);}
102
+    bool onTouchHeld(uint8_t tag)  {return GET_METHOD(type, onTouchHeld)(tag);}
103
+    bool onTouchEnd(uint8_t tag)   {return GET_METHOD(type, onTouchEnd)(tag);}
104
+
105
+    void initializeAll();
106
+};
107
+
108
+/********************** SCREEN STACK  ******************************/
109
+
110
+// To conserve dynamic memory, the screen stack is hard-coded to
111
+// have four values, allowing a menu of up to four levels.
112
+
113
+class ScreenStack : public ScreenRef {
114
+  private:
115
+    uint8_t stack[4];
116
+
117
+  public:
118
+    void start();
119
+    void push(onRedraw_func_t);
120
+    void push();
121
+    void pop();
122
+    void forget();
123
+    void goTo(onRedraw_func_t);
124
+    void goBack();
125
+
126
+    uint8_t peek()      {return stack[0];}
127
+    uint8_t getScreen() {return getType();}
128
+};
129
+
130
+extern ScreenStack current_screen;
131
+
132
+/********************** BASE SCREEN CLASS ******************************/
133
+
134
+/* UIScreen is the base class for all user interface screens.
135
+ */
136
+class UIScreen {
137
+  public:
138
+    static void onStartup()            {}
139
+    static void onEntry()              {current_screen.onRefresh();}
140
+    static void onExit()               {}
141
+    static void onIdle()               {}
142
+    static bool onTouchStart(uint8_t)  {return true;}
143
+    static bool onTouchHeld(uint8_t)   {return false;}
144
+    static bool onTouchEnd(uint8_t)    {return true;}
145
+};
146
+
147
+#define PUSH_SCREEN(screen)   current_screen.push(screen::onRedraw);
148
+#define GOTO_SCREEN(screen)   current_screen.goTo(screen::onRedraw);
149
+#define GOTO_PREVIOUS()       current_screen.goBack();
150
+#define AT_SCREEN(screen)     (current_screen.getType() == current_screen.lookupScreen(screen::onRedraw))
151
+#define IS_PARENT_SCREEN(screen) (current_screen.peek() == current_screen.lookupScreen(screen::onRedraw))
152
+
153
+/************************** CACHED VS UNCHACHED SCREENS ***************************/
154
+
155
+class UncachedScreen {
156
+  public:
157
+    static void onRefresh() {
158
+      using namespace FTDI;
159
+      CLCD::CommandFifo cmd;
160
+      cmd.cmd(CMD_DLSTART);
161
+
162
+      current_screen.onRedraw(BOTH);
163
+
164
+      cmd.cmd(DL::DL_DISPLAY);
165
+      cmd.cmd(CMD_SWAP);
166
+      cmd.execute();
167
+    }
168
+};
169
+
170
+template<uint8_t DL_SLOT,uint32_t DL_SIZE = 0>
171
+class CachedScreen {
172
+  protected:
173
+    static bool storeBackground(){
174
+      DLCache dlcache(DL_SLOT);
175
+      if (!dlcache.store(DL_SIZE)) {
176
+        SERIAL_ECHO_START();
177
+        SERIAL_ECHOLNPGM("CachedScreen::storeBackground() failed: not enough DL cache space");
178
+        return false;
179
+      }
180
+      return true;
181
+    }
182
+
183
+    static void repaintBackground(){
184
+      using namespace FTDI;
185
+      DLCache dlcache(DL_SLOT);
186
+      CLCD::CommandFifo cmd;
187
+
188
+      cmd.cmd(CMD_DLSTART);
189
+      current_screen.onRedraw(BACKGROUND);
190
+
191
+      dlcache.store(DL_SIZE);
192
+    }
193
+
194
+  public:
195
+    static void onRefresh(){
196
+      using namespace FTDI;
197
+      DLCache dlcache(DL_SLOT);
198
+      CLCD::CommandFifo cmd;
199
+
200
+      cmd.cmd(CMD_DLSTART);
201
+
202
+      if (dlcache.has_data()) {
203
+        dlcache.append();
204
+      } else {
205
+        current_screen.onRedraw(BACKGROUND);
206
+        dlcache.store(DL_SIZE);
207
+      }
208
+
209
+      current_screen.onRedraw(FOREGROUND);
210
+
211
+      cmd.cmd(DL::DL_DISPLAY);
212
+      cmd.cmd(CMD_SWAP);
213
+      cmd.execute();
214
+    }
215
+};

+ 38
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_list.h View File

@@ -0,0 +1,38 @@
1
+/****************
2
+ * sound_list.h *
3
+ ****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#pragma once
23
+
24
+class SoundList {
25
+  private:
26
+    static PROGMEM const struct list_t {
27
+      const char *const PROGMEM name;
28
+      const FTDI::SoundPlayer::sound_t* data;
29
+    } list[];
30
+  public:
31
+    static const uint8_t n;
32
+    static inline const char* name(uint8_t val) {
33
+      return (const char* ) pgm_read_ptr_near(&list[val].name);
34
+    }
35
+    static inline FTDI::SoundPlayer::sound_t* data(uint8_t val) {
36
+      return (FTDI::SoundPlayer::sound_t*) pgm_read_ptr_near(&list[val].data);
37
+    }
38
+};

+ 111
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.cpp View File

@@ -0,0 +1,111 @@
1
+/********************
2
+ * sound_player.cpp *
3
+ ********************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#include "ftdi_extended.h"
23
+
24
+#ifdef FTDI_EXTENDED
25
+
26
+namespace FTDI {
27
+  SoundPlayer sound; // Global sound player object
28
+
29
+  void SoundPlayer::set_volume(uint8_t vol) {
30
+    CLCD::mem_write_8(REG::VOL_SOUND, vol);
31
+  }
32
+
33
+  uint8_t SoundPlayer::get_volume() {
34
+    return CLCD::mem_read_8(REG::VOL_SOUND);
35
+  }
36
+
37
+  void SoundPlayer::play(effect_t effect, note_t note) {
38
+
39
+    #ifdef UI_FRAMEWORK_DEBUG
40
+      SERIAL_ECHO_START();
41
+      SERIAL_ECHOPAIR("Playing note ", note);
42
+      SERIAL_ECHOLNPAIR(", instrument ", effect);
43
+    #endif
44
+
45
+    // Play the note
46
+    CLCD::mem_write_16(REG::SOUND, (note == REST) ? 0 : (((note ? note : NOTE_C4) << 8) | effect));
47
+    CLCD::mem_write_8(REG::PLAY, 1);
48
+  }
49
+
50
+  note_t SoundPlayer::frequency_to_midi_note(const uint16_t frequency_hz) {
51
+    const float f0 = 440;
52
+    return note_t(NOTE_A4 + (log(frequency_hz)-log(f0))*12/log(2) + 0.5);
53
+  }
54
+
55
+  // Plays a tone of a given frequency and duration. Since the FTDI FT810 only
56
+  // supports MIDI notes, we round down to the nearest note.
57
+
58
+  void SoundPlayer::play_tone(const uint16_t frequency_hz, const uint16_t duration_ms) {
59
+    play(ORGAN, frequency_to_midi_note(frequency_hz));
60
+
61
+    // Schedule silence to squelch the note after the duration expires.
62
+    sequence = silence;
63
+    wait = duration_ms;
64
+    timer.start();
65
+  }
66
+
67
+  void SoundPlayer::play(const sound_t* seq, play_mode_t mode) {
68
+    sequence = seq;
69
+    wait     = 250; // Adding this delay causes the note to not be clipped, not sure why.
70
+    timer.start();
71
+
72
+    if (mode == PLAY_ASYNCHRONOUS) return;
73
+
74
+    // If playing synchronously, then play all the notes here
75
+
76
+    while (has_more_notes()) {
77
+      onIdle();
78
+      #ifdef EXTENSIBLE_UI
79
+        ExtUI::yield();
80
+      #endif
81
+    }
82
+  }
83
+
84
+  bool SoundPlayer::is_sound_playing() {
85
+    return CLCD::mem_read_8( REG::PLAY ) & 0x1;
86
+  }
87
+
88
+  void SoundPlayer::onIdle() {
89
+    if (!sequence) return;
90
+
91
+    const bool ready_for_next_note = (wait == 0) ? !is_sound_playing() : timer.elapsed(wait);
92
+
93
+    if (ready_for_next_note) {
94
+      const effect_t fx = effect_t(pgm_read_byte(&sequence->effect));
95
+      const note_t   nt =   note_t(pgm_read_byte(&sequence->note));
96
+      const uint32_t ms = uint32_t(pgm_read_byte(&sequence->sixteenths)) * 1000 / 16;
97
+
98
+      if (ms == 0 && fx == SILENCE && nt == END_SONG) {
99
+        sequence = 0;
100
+        play(SILENCE, REST);
101
+      } else {
102
+        wait = ms;
103
+        timer.start();
104
+        play(fx, nt);
105
+        sequence++;
106
+      }
107
+    }
108
+  }
109
+} // namespace FTDI
110
+
111
+#endif // FTDI_EXTENDED

+ 70
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.h View File

@@ -0,0 +1,70 @@
1
+/******************
2
+ * sound_player.h *
3
+ ******************/
4
+
5
+/****************************************************************************
6
+ *   Written By Mark Pelletier  2017 - Aleph Objects, Inc.                  *
7
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
8
+ *                                                                          *
9
+ *   This program is free software: you can redistribute it and/or modify   *
10
+ *   it under the terms of the GNU General Public License as published by   *
11
+ *   the Free Software Foundation, either version 3 of the License, or      *
12
+ *   (at your option) any later version.                                    *
13
+ *                                                                          *
14
+ *   This program is distributed in the hope that it will be useful,        *
15
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
16
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
17
+ *   GNU General Public License for more details.                           *
18
+ *                                                                          *
19
+ *   To view a copy of the GNU General Public License, go to the following  *
20
+ *   location: <http://www.gnu.org/licenses/>.                              *
21
+ ****************************************************************************/
22
+
23
+#pragma once
24
+
25
+namespace FTDI {
26
+  typedef enum {
27
+    PLAY_ASYNCHRONOUS,
28
+    PLAY_SYNCHRONOUS
29
+  } play_mode_t;
30
+
31
+  class SoundPlayer {
32
+    typedef FTDI::ftdi_registers  REG;
33
+    typedef FTDI::ftdi_memory_map MAP;
34
+
35
+    public:
36
+      struct sound_t {
37
+        effect_t  effect;      // The sound effect number
38
+        note_t    note;        // The MIDI note value
39
+        uint16_t  sixteenths;  // Duration of note, in sixteeths of a second, or zero to play to completion
40
+      };
41
+
42
+      const uint8_t WAIT = 0;
43
+
44
+    private:
45
+      const sound_t   *sequence;
46
+      tiny_timer_t     timer;
47
+      tiny_time_t      wait;
48
+
49
+      note_t frequency_to_midi_note(const uint16_t frequency);
50
+
51
+    public:
52
+      static void set_volume(uint8_t volume);
53
+      static uint8_t get_volume();
54
+
55
+      static void play(effect_t effect, note_t note = NOTE_C4);
56
+      static bool is_sound_playing();
57
+
58
+      void play(const sound_t* seq, play_mode_t mode = PLAY_SYNCHRONOUS);
59
+      void play_tone(const uint16_t frequency_hz, const uint16_t duration_ms);
60
+      bool has_more_notes() {return sequence != 0;};
61
+
62
+      void onIdle();
63
+  };
64
+
65
+  extern SoundPlayer sound;
66
+
67
+  const PROGMEM SoundPlayer::sound_t silence[] = {
68
+    {SILENCE,      END_SONG, 0}
69
+  };
70
+}

+ 0
- 0
Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/text_box.cpp View File


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

Loading…
Cancel
Save