diff --git a/Marlin/AO_FT810_Constants.h b/Marlin/AO_FT810_Constants.h
new file mode 100644
index 000000000..545f5beb9
--- /dev/null
+++ b/Marlin/AO_FT810_Constants.h
@@ -0,0 +1,645 @@
+/***********
+ * FT810.h *
+ ***********/
+
+
+/****************************************************************************
+ * Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * To view a copy of the GNU General Public License, go to the following *
+ * location: . *
+ ****************************************************************************/
+
+/****************************************************************************
+ * This header defines registers and commands for the FTDI FT810 LCD Driver *
+ * chip. *
+ ****************************************************************************/
+
+
+/************************************************************************************************************
+ * FT810 *
+ * *
+ * START ADDRESS END ADDRESS SIZE NAME DESCRIPTION *
+ * *
+ * 0x000000 0x0FFFFF 1024 kB RAM_G Main Graphics RAM 0 to 1048572 *
+ * *
+ * 0x0C0000 0x0C0003 4 B ROM_CHIPID [0:1] 0x800 [1:2] 0x0100 Chip Id, Version ID *
+ * *
+ * 0x1E0000 0x2FFFFB 1152 kB ROM_FONT Font table and bitmap *
+ * *
+ * 0x2FFFFC 0x2FFFFF 4 B ROM_FONT_ADDR Font table pointer address *
+ * *
+ * 0x300000 0x301FFF 8 kB RAM_DL Display List RAM *
+ * *
+ * 0x302000 0x302FFF 4 kB REG_* Registers *
+ * *
+ * 0x308000 0x308FFF 4 kB RAM_CMD Command Buffer *
+ * *
+ ************************************************************************************************************/
+
+#ifndef _AO_FT810_H
+#define _AO_FT810_H
+
+// Uncomment this line if using an Arduino board instead of a Printer Controller board.
+// This allows the use of the Arduino SPI Library and SPI Peripheral instead of the bit-banged SPI
+// of the Printer Controllers (RAMBo, Mini RAMBo, Einsy, Archim).
+// This is used by the CLCD_spiTransfer(uint8_t) function and CLCD_spiInit() function.
+
+// #define IS_ARDUINO
+
+namespace FT800 {
+ // MEMORY LOCATIONS FT800
+ const uint32_t RAM_G = 0x000000; // Main Graphics RAM
+ const uint32_t ROM_FONT = 0x0BB23C; // Font ROM
+ const uint32_t ROM_FONT_ADDR = 0x0FFFFC; // Font Table Pointer
+ const uint32_t RAM_DL = 0x100000; // Display List RAM
+ const uint32_t RAM_PAL = 0x102000; // Palette RAM
+ const uint32_t RAM_REG = 0x102400; // Registers
+ const uint32_t RAM_CMD = 0x108000; // Command Buffer
+}
+
+namespace FT810 {
+ // MEMORY LOCATIONS FT810
+ const uint32_t RAM_G = 0x000000; // Main Graphics RAM
+ const uint32_t ROM_CHIPID = 0x0C0000; // Chip ID ROM
+ const uint32_t ROM_FONT = 0x1E0000; // Font ROM
+ const uint32_t ROM_FONT_ADDR = 0x2FFFFC; // Font Table Pointer
+ const uint32_t RAM_DL = 0x300000; // Display List RAM
+ const uint32_t RAM_REG = 0x302000; // Registers
+ const uint32_t RAM_CMD = 0x308000; // Command Buffer
+}
+
+namespace FT800 {
+ // REGISTERS AND ADDRESSES FT800
+
+ // REGISTER ADDRESS SIZE RESET VALUE TYPE DESCRIPTION
+
+ const uint32_t REG_ID = 0x102400; // 8 0x7C r Identification Register, Always 0x7C
+ const uint32_t REG_FRAMES = 0x102404; // 32 0x00000000 r Frame Counter, Since Reset
+ const uint32_t REG_CLOCK = 0x102408; // 32 0x00000000 r Clock cycles, Since Reset
+ const uint32_t REG_FREQUENCY = 0x10240C; // 28 0x03938700 r/w Main Clock Frequency
+ const uint32_t REG_RENDERMODE = 0x102410; // 1 0x00 r/w Rendering Mode: 0 = normal, 1 = single-line
+ const uint32_t REG_SNAPY = 0x102414; // 11 0x0000 r/w Scan Line Select for RENDERMODE 1
+ const uint32_t REG_SNAPSHOT = 0x102418; // 1 - r Trigger for RENDERMODE 1
+ const uint32_t REG_CPURESET = 0x10241C; // 3 0x02 r/w RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics
+ const uint32_t REG_TAP_CRC = 0x102420; // 32 - r Live Video Tap
+ const uint32_t REG_TAP_MASK = 0x102424; // 32 0xFFFFFFFF r/w Live Video Tap Mask
+ const uint32_t REG_HCYCLE = 0x102428; // 12 0x224 r/w Horizontal Total Cycle Count
+ const uint32_t REG_HOFFSET = 0x10242C; // 12 0x02B r/w Horizontal Display Start Offset
+ const uint32_t REG_HSIZE = 0x102430; // 12 0x1E0 r/w Horizontal Display Pixel Count
+ const uint32_t REG_HSYNC0 = 0x102434; // 12 0x000 r/w Horizontal Sync Fall Offset
+ const uint32_t REG_HSYNC1 = 0x102438; // 12 0x029 r/w Horizontal Sync Rise Offset
+ const uint32_t REG_VCYCLE = 0x10243C; // 12 0x124 r/w Vertical Total Cycle Count
+ const uint32_t REG_VOFFSET = 0x102440; // 12 0x00C r/w Vertical Display Start Offset
+ const uint32_t REG_VSIZE = 0x102444; // 12 0x110 r/w Vertical Display Line Count
+ const uint32_t REG_VSYNC0 = 0x102448; // 10 0x000 r/w Vertical Sync Fall Offset
+ const uint32_t REG_VSYNC1 = 0x10244C; // 10 0x00A r/w Vertical Sync Rise Offset
+ const uint32_t REG_DLSWAP = 0x102450; // 2 0x00 r/w Display List Swap Control
+ const uint32_t REG_ROTATE = 0x102454; // 3 0x00 r/w Screen 90,180, 270 degree rotate
+ const uint32_t REG_OUTBITS = 0x102458; // 9 0x1B6 r/w Output Resolution, 3x3x3 Bits
+ const uint32_t REG_DITHER = 0x10245C; // 1 0x01 r/w Output Dither Enable
+ const uint32_t REG_SWIZZLE = 0x102460; // 4 0x00 r/w Output RGB Swizzle, Pin Change for PCB Routing
+ const uint32_t REG_CSPREAD = 0x102464; // 1 0x01 r/w Output Clock Spreading Enable
+ const uint32_t REG_PCLK_POL = 0x102468; // 1 0x00 r/w PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge
+ const uint32_t REG_PCLK = 0x10246C; // 8 0x00 r/w PCLK Frequency Divider, 0 = Disable Clock
+ const uint32_t REG_TAG_X = 0x102470; // 11 0x000 r/w Tag Query X Coordinate
+ const uint32_t REG_TAG_Y = 0x102474; // 11 0x000 r/w Tag Query Y Coordinate
+ const uint32_t REG_TAG = 0x102478; // 8 0x00 r Tag Query Result
+ const uint32_t REG_VOL_PB = 0x10247C; // 8 0xFF r/w Audio Playback Volume
+ const uint32_t REG_VOL_SOUND = 0x102480; // 8 0xFF r/w Audio Synthesizer Volume
+ const uint32_t REG_SOUND = 0x102484; // 16 0x0000 r/w Audio Sound Effect Select
+ const uint32_t REG_PLAY = 0x102488; // 1 0x00 r/w Audio Start Effect Playback
+ const uint32_t REG_GPIO_DIR = 0x10248C; // 8 0x80 r/w GPIO Pin Direction: 0 = Input , 1 = Output
+ const uint32_t REG_GPIO = 0x102490; // 8 0x00 r/w GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6
+ const uint32_t REG_INT_FLAGS = 0x102498; // 8 0x00 r Interrupt Flags, Clear by Reading
+ const uint32_t REG_INT_EN = 0x10249C; // 1 0x00 r/w Global Interrupt Enable
+ const uint32_t REG_INT_MASK = 0x1024A0; // 8 0xFF r/w Interrupt Enable Mask
+ const uint32_t REG_PLAYBACK_START = 0x1024A4; // 20 0x00000 r/w Audio Playback RAM Start Address
+ const uint32_t REG_PLAYBACK_LENGTH = 0x1024A8; // 20 0x00000 r/w Audio Playback Sample Length (Bytes)
+ const uint32_t REG_PLAYBACK_READPTR = 0x1024AC; // 20 - r Audio Playback Read Pointer
+ const uint32_t REG_PLAYBACK_FREQ = 0x1024B0; // 16 0x1F40 r/w Audio Playback Frequency (Hz)
+ const uint32_t REG_PLAYBACK_FORMAT = 0x1024B4; // 2 0x00 r/w Audio Playback Format
+ const uint32_t REG_PLAYBACK_LOOP = 0x1024B8; // 1 0x00 r/w Audio Playback Loop Enable
+ const uint32_t REG_PLAYBACK_PLAY = 0x1024BC; // 1 0x00 r Audio Start Playback
+ const uint32_t REG_PWM_HZ = 0x1024C0; // 14 0x00FA r/w Backlight PWM Frequency (Hz)
+ const uint32_t REG_PWM_DUTY = 0x1024C4; // 8 0x80 r/w Backlight PWM Duty Cycle: 0 = 0%, 128 = 100%
+ const uint32_t REG_MACRO_0 = 0x1024C8; // 32 0x00000000 r/w Display List Macro Command 0
+ const uint32_t REG_MACRO_1 = 0x1024CC; // 32 0x00000000 r/w Display List Macro Command 1
+ const uint32_t REG_CMD_READ = 0x1024E4; // 12 0x000 r/w Command Buffer Read Pointer
+ const uint32_t REG_CMD_WRITE = 0x1024E8; // 12 0x000 r/w Command Buffer Write Pointer
+ const uint32_t REG_CMD_DL = 0x1024EC; // 13 0x0000 r/w Command Display List Offset
+ const uint32_t REG_TOUCH_MODE = 0x1024F0; // 2 0x03 r/w Touch-Screen Sampling Mode
+ const uint32_t REG_TOUCH_ADC_MODE = 0x1024F4; // 1 0x01 r/w Select Single Ended or Differential Sampling
+ const uint32_t REG_TOUCH_CHARGE = 0x1024F8; // 16 0x1770 r/w Touch Screen Charge Time, n x 6 Clocks
+ const uint32_t REG_TOUCH_SETTLE = 0x1024FC; // 4 0x03 r/w Touch-Screen Settle Time, n x 6 Clocks
+ const uint32_t REG_TOUCH_OVERSAMPLE = 0x102500; // 4 0x07 r/w Touch-Screen Oversample Factor
+ const uint32_t REG_TOUCH_RZTHRESH = 0x102504; // 16 0xFFFF r/w Touch-Screen Resistance Threshold
+ const uint32_t REG_TOUCH_RAW_XY = 0x102508; // 32 - r Touch-Screen Raw (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_RZ = 0x10250C; // 16 - r Touch-Screen Resistance
+ const uint32_t REG_TOUCH_SCREEN_XY = 0x102510; // 32 - r Touch-Screen Screen (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_TAG_XY = 0x102514; // 32 - r Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_TAG = 0x102518; // 8 - r Touch-Screen Tag 0 Result
+ const uint32_t REG_TOUCH_TRANSFORM_A = 0x10251C; // 32 0x00010000 r/w Touch-Screen Transform Coefficient A (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_B = 0x102520; // 32 0x00000000 r/w Touch-Screen Transform Coefficient B (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_C = 0x102524; // 32 0x00000000 r/w Touch-Screen Transform Coefficient C (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_D = 0x102528; // 32 0x00000000 r/w Touch-Screen Transform Coefficient D (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_E = 0x10252C; // 32 0x00010000 r/w Touch-Screen Transform Coefficient E (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_F = 0x102530; // 32 0x00000000 r/w Touch-Screen Transform Coefficient F (s15.16)
+// Reserved Addresses 0x102434 - 0x102470
+ const uint32_t REG_TOUCH_DIRECT_XY = 0x102574; // 32 - r Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_DIRECT_Z1Z2 = 0x102578; // 32 - r Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16)
+ const uint32_t REG_TRACKER = 0x109000; // 32 0x00000000 r/w Track Register (Track Value – MSB16; Tag Value - LSB8)
+};
+
+namespace FT810 {
+ // REGISTERS AND ADDRESSES FT810
+
+ // REGISTER ADDRESS SIZE RESET VALUE TYPE DESCRIPTION
+
+ const uint32_t REG_ID = 0x302000; // 8 0x7C r Identification Register, Always 0x7C
+ const uint32_t REG_FRAMES = 0x302004; // 32 0x00000000 r Frame Counter, Since Reset
+ const uint32_t REG_CLOCK = 0x302008; // 32 0x00000000 r Clock cycles, Since Reset
+ const uint32_t REG_FREQUENCY = 0x30200C; // 28 0x03938700 r/w Main Clock Frequency
+ const uint32_t REG_RENDERMODE = 0x302010; // 1 0x00 r/w Rendering Mode: 0 = normal, 1 = single-line
+ const uint32_t REG_SNAPY = 0x302014; // 11 0x0000 r/w Scan Line Select for RENDERMODE 1
+ const uint32_t REG_SNAPSHOT = 0x302018; // 1 - r Trigger for RENDERMODE 1
+ const uint32_t REG_SNAPFORMAT = 0x30201C; // 6 0x20 r/w Pixel Format for Scanline Readout
+ const uint32_t REG_CPURESET = 0x302020; // 3 0x02 r/w RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics
+ const uint32_t REG_TAP_CRC = 0x302024; // 32 - r Live Video Tap
+ const uint32_t REG_TAP_MASK = 0x302028; // 32 0xFFFFFFFF r/w Live Video Tap Mask
+ const uint32_t REG_HCYCLE = 0x30202C; // 12 0x224 r/w Horizontal Total Cycle Count
+ const uint32_t REG_HOFFSET = 0x302030; // 12 0x02B r/w Horizontal Display Start Offset
+ const uint32_t REG_HSIZE = 0x302034; // 12 0x1E0 r/w Horizontal Display Pixel Count
+ const uint32_t REG_HSYNC0 = 0x302038; // 12 0x000 r/w Horizontal Sync Fall Offset
+ const uint32_t REG_HSYNC1 = 0x30203C; // 12 0x029 r/w Horizontal Sync Rise Offset
+ const uint32_t REG_VCYCLE = 0x302040; // 12 0x124 r/w Vertical Total Cycle Count
+ const uint32_t REG_VOFFSET = 0x302044; // 12 0x00C r/w Vertical Display Start Offset
+ const uint32_t REG_VSIZE = 0x302048; // 12 0x110 r/w Vertical Display Line Count
+ const uint32_t REG_VSYNC0 = 0x30204C; // 10 0x000 r/w Vertical Sync Fall Offset
+ const uint32_t REG_VSYNC1 = 0x302050; // 10 0x00A r/w Vertical Sync Rise Offset
+ const uint32_t REG_DLSWAP = 0x302054; // 2 0x00 r/w Display List Swap Control
+ const uint32_t REG_ROTATE = 0x302058; // 3 0x00 r/w Screen 90,180, 270 degree rotate
+ const uint32_t REG_OUTBITS = 0x30205C; // 9 0x1B6 r/w Output Resolution, 3x3x3 Bits
+ const uint32_t REG_DITHER = 0x302060; // 1 0x01 r/w Output Dither Enable
+ const uint32_t REG_SWIZZLE = 0x302064; // 4 0x00 r/w Output RGB Swizzle, Pin Change for PCB Routing
+ const uint32_t REG_CSPREAD = 0x302068; // 1 0x01 r/w Output Clock Spreading Enable
+ const uint32_t REG_PCLK_POL = 0x30206C; // 1 0x00 r/w PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge
+ const uint32_t REG_PCLK = 0x302070; // 8 0x00 r/w PCLK Frequency Divider, 0 = Disable Clock
+ const uint32_t REG_TAG_X = 0x302074; // 11 0x000 r/w Tag Query X Coordinate
+ const uint32_t REG_TAG_Y = 0x302078; // 11 0x000 r/w Tag Query Y Coordinate
+ const uint32_t REG_TAG = 0x30207C; // 8 0x00 r Tag Query Result
+ const uint32_t REG_VOL_PB = 0x302080; // 8 0xFF r/w Audio Playback Volume
+ const uint32_t REG_VOL_SOUND = 0x302084; // 8 0xFF r/w Audio Synthesizer Volume
+ const uint32_t REG_SOUND = 0x302088; // 16 0x0000 r/w Audio Sound Effect Select
+ const uint32_t REG_PLAY = 0x30208C; // 1 0x00 r/w Audio Start Effect Playback
+ const uint32_t REG_GPIO_DIR = 0x302090; // 8 0x80 r/w GPIO Pin Direction: 0 = Input , 1 = Output
+ const uint32_t REG_GPIO = 0x302094; // 8 0x00 r/w GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6
+ const uint32_t REG_GPIOX_DIR = 0x302098; // 16 0x8000 r/w Extended GPIO Pin Direction
+ const uint32_t REG_GPIOX = 0x30209C; // 16 0x0080 r/w Extended GPIO Pin Values
+ // Reserved Addr 0x3020A0
+ // Reserved Addr 0x3020A4
+ const uint32_t REG_INT_FLAGS = 0x3020A8; // 8 0x00 r Interrupt Flags, Clear by Reading
+ const uint32_t REG_INT_EN = 0x3020AC; // 1 0x00 r/w Global Interrupt Enable
+ const uint32_t REG_INT_MASK = 0x3020B0; // 8 0xFF r/w Interrupt Enable Mask
+ const uint32_t REG_PLAYBACK_START = 0x3020B4; // 20 0x00000 r/w Audio Playback RAM Start Address
+ const uint32_t REG_PLAYBACK_LENGTH = 0x3020B8; // 20 0x00000 r/w Audio Playback Sample Length (Bytes)
+ const uint32_t REG_PLAYBACK_READPTR = 0x3020BC; // 20 - r Audio Playback Read Pointer
+ const uint32_t REG_PLAYBACK_FREQ = 0x3020C0; // 16 0x1F40 r/w Audio Playback Frequency (Hz)
+ const uint32_t REG_PLAYBACK_FORMAT = 0x3020C4; // 2 0x00 r/w Audio Playback Format
+ const uint32_t REG_PLAYBACK_LOOP = 0x3020C8; // 1 0x00 r/w Audio Playback Loop Enable
+ const uint32_t REG_PLAYBACK_PLAY = 0x3020CC; // 1 0x00 r Audio Start Playback
+ const uint32_t REG_PWM_HZ = 0x3020D0; // 14 0x00FA r/w Backlight PWM Frequency (Hz)
+ const uint32_t REG_PWM_DUTY = 0x3020D4; // 8 0x80 r/w Backlight PWM Duty Cycle: 0 = 0%, 128 = 100%
+ const uint32_t REG_MACRO_0 = 0x3020D8; // 32 0x00000000 r/w Display List Macro Command 0
+ const uint32_t REG_MACRO_1 = 0x3020DC; // 32 0x00000000 r/w Display List Macro Command 1
+ // Reserved Addr 0x3020E0
+ // Reserved Addr 0x3020E4
+ // Reserved Addr 0x3020E8
+ // Reserved Addr 0x3020EC
+ // Reserved Addr 0x3020F0
+ // Reserved Addr 0x3020F4
+ const uint32_t REG_CMD_READ = 0x3020F8; // 12 0x000 r/w Command Buffer Read Pointer
+ const uint32_t REG_CMD_WRITE = 0x3020FC; // 12 0x000 r/w Command Buffer Write Pointer
+ const uint32_t REG_CMD_DL = 0x302100; // 13 0x0000 r/w Command Display List Offset
+ const uint32_t REG_TOUCH_MODE = 0x302104; // 2 0x03 r/w Touch-Screen Sampling Mode
+ const uint32_t REG_TOUCH_ADC_MODE = 0x302108; // 1 0x01 r/w Select Single Ended or Differential Sampling
+ const uint32_t REG_TOUCH_CHARGE = 0x30210C; // 16 0x1770 r/w Touch Screen Charge Time, n x 6 Clocks
+ const uint32_t REG_TOUCH_SETTLE = 0x302110; // 4 0x03 r/w Touch-Screen Settle Time, n x 6 Clocks
+ const uint32_t REG_TOUCH_OVERSAMPLE = 0x302114; // 4 0x07 r/w Touch-Screen Oversample Factor
+ const uint32_t REG_TOUCH_RZTHRESH = 0x302118; // 16 0xFFFF r/w Touch-Screen Resistance Threshold
+ const uint32_t REG_TOUCH_RAW_XY = 0x30211C; // 32 - r Touch-Screen Raw (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_RZ = 0x302120; // 16 - r Touch-Screen Resistance
+ const uint32_t REG_TOUCH_SCREEN_XY = 0x302124; // 32 - r Touch-Screen Screen (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_TAG_XY = 0x302128; // 32 - r Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_TAG = 0x30212C; // 8 - r Touch-Screen Tag 0 Result
+ const uint32_t REG_TOUCH_TAG1_XY = 0x302130; // 32 - r Touch-Screen Tag 1 Lookup
+ const uint32_t REG_TOUCH_TAG1 = 0x302134; // 8 - r Touch-Screen Tag 1 Result
+ const uint32_t REG_TOUCH_TAG2_XY = 0x302138; // 32 - r Touch-Screen Tag 2 Lookup
+ const uint32_t REG_TOUCH_TAG2 = 0x30213C; // 8 - r Touch-Screen Tag 2 Result
+ const uint32_t REG_TOUCH_TAG3_XY = 0x302140; // 32 - r Touch-Screen Tag 3 Lookup
+ const uint32_t REG_TOUCH_TAG3 = 0x302144; // 8 - r Touch-Screen Tag 3 Result
+ const uint32_t REG_TOUCH_TAG4_XY = 0x302148; // 32 - r Touch-Screen Tag 4 Lookup
+ const uint32_t REG_TOUCH_TAG4 = 0x30214C; // 8 - r Touch-Screen Tag 4 Result
+ const uint32_t REG_TOUCH_TRANSFORM_A = 0x302150; // 32 0x00010000 r/w Touch-Screen Transform Coefficient A (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_B = 0x302154; // 32 0x00000000 r/w Touch-Screen Transform Coefficient B (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_C = 0x302158; // 32 0x00000000 r/w Touch-Screen Transform Coefficient C (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_D = 0x30215C; // 32 0x00000000 r/w Touch-Screen Transform Coefficient D (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_E = 0x302160; // 32 0x00010000 r/w Touch-Screen Transform Coefficient E (s15.16)
+ const uint32_t REG_TOUCH_TRANSFORM_F = 0x302164; // 32 0x00000000 r/w Touch-Screen Transform Coefficient F (s15.16)
+ const uint32_t REG_TOUCH_CONFIG = 0x302168; // 16 0x8381 r/w Touch Configuration
+ const uint32_t REG_CTOUCH_TOUCH4_X = 0x30216C; // 16 - r Extended Mode Touch Screen
+ // Reserved Addresses 0x302170
+ const uint32_t REG_BIST_EN = 0x302174; // 1 0 r/w BIST Memory Mapping Enable
+ // Reserved Addr 0x302178
+ // Reserved Addr 0x30217C
+ const uint32_t REG_TRIM = 0x302180; // 8 0 r/w Internal Clock Trimming
+ const uint32_t REG_ANA_COMP = 0x302184; // 8 0 r/w Analog Control Register
+ const uint32_t REG_SPI_WIDTH = 0x302188; // 3 0 r/w QSPI Bus Width Setting
+ const uint32_t REG_TOUCH_DIRECT_XY = 0x30218C; // 32 - r Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16)
+ const uint32_t REG_TOUCH_DIRECT_Z1Z2 = 0x302190; // 32 - r Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16)
+ // Reserved Addresses 0x302194 - 0x302560
+ const uint32_t REG_DATESTAMP = 0x320564; // 128 - r Stamp Date Code
+ const uint32_t REG_CMDB_SPACE = 0x302574; // 12 0xFFC r/w Command DL Space Available
+ const uint32_t REG_CMDB_WRITE = 0x302578; // 32 0 w Command DL Write
+}
+
+// OPTIONS
+
+namespace FTDI {
+ const uint16_t OPT_3D = 0;
+ const uint16_t OPT_RGB565 = 0;
+ const uint16_t OPT_MONO = 1;
+ const uint16_t OPT_NODL = 2;
+ const uint16_t OPT_FLAT = 256;
+ const uint16_t OPT_SIGNED = 256;
+ const uint16_t OPT_CENTERX = 512;
+ const uint16_t OPT_CENTERY = 1024;
+ const uint16_t OPT_CENTER = 1536;
+ const uint16_t OPT_RIGHTX = 2048;
+ const uint16_t OPT_NOBACK = 4096;
+ const uint16_t OPT_NOTICKS = 8192;
+ const uint16_t OPT_NOHM = 16384;
+ const uint16_t OPT_NOPOINTER = 16384;
+ const uint16_t OPT_NOSECS = 32768;
+ const uint16_t OPT_NOHANDS = 49152;
+}
+
+// GLOBAL LCD REGISTER SET VALUES FOR WQVGA 480x272 DISPLAY
+
+/*
+ * Settings for the Aleph Objects Color LCD User Interface 4.3" (Prototype) 480x272, SPI, FT810 (HDA430T-6S-WV)
+ * Haoyu Electronics, 4.3" Graphical LCD Touchscreen, 480x272, SPI, FT800 (FT800CB-HY43B)
+ * Haoyu Electronics, 5" Graphical LCD Touchscreen, 480x272, SPI, FT800 (FT800CB-HY50B)
+ * 4D Systems, 4.3" Embedded SPI Display 480x272, SPI, FT800 (4DLCD-FT843)
+ *
+ * http://www.hotmcu.com/43-graphical-lcd-touchscreen-480x272-spi-ft800-p-111.html?cPath=6_16
+ * http://www.hotmcu.com/5-graphical-lcd-touchscreen-480x272-spi-ft800-p-124.html?cPath=6_16
+ * http://www.4dsystems.com.au/product/4DLCD_FT843/
+ *
+ * Datasheet:
+ *
+ * http://www.hantronix.com/files/data/1278363262430-3.pdf
+ * http://www.haoyuelectronics.com/Attachment/HY43-LCD/LCD%20DataSheet.pdf
+ * http://www.haoyuelectronics.com/Attachment/HY5-LCD-HD/KD50G21-40NT-A1.pdf
+ * http://www.4dsystems.com.au/productpages/4DLCD-FT843/downloads/FT843-4.3-Display_datasheet_R_1_2.pdf
+ *
+ */
+namespace FTDI_LCD_480x272 {
+ const int Vsync0 = 0;
+ const int Vsync1 = 10;
+ const int Voffset = 12;
+ const int Vcycle = 292;
+ const int Hsync0 = 0;
+ const int Hsync1 = 41;
+ const int Hoffset = 43;
+ const int Hcycle = 548;
+ const int Hsize = 480;
+ const int Vsize = 272;
+ const int Pclkpol = 1;
+ const int Swizzle = 0;
+ const int Pclk = 5;
+ const int Clksel = 0x44;
+
+ const uint32_t default_transform_a = 0x00008100;
+ const uint32_t default_transform_b = 0x00000000;
+ const uint32_t default_transform_c = 0xFFF18000;
+ const uint32_t default_transform_d = 0x00000000;
+ const uint32_t default_transform_e = 0xFFFFB100;
+ const uint32_t default_transform_f = 0x0120D000;
+}
+
+// GLOBAL LCD REGISTER SET VALUES FOR 800x480 DISPLAY
+
+/*
+ * Settings for the Haoyu Electronics, 5" Graphical LCD Touchscreen, 800x480, SPI, FT810
+ *
+ * http://www.hotmcu.com/5-graphical-lcd-touchscreen-800x480-spi-ft810-p-286.html
+ *
+ * Datasheet:
+ *
+ * http://www.haoyuelectronics.com/Attachment/HY5-LCD-HD/KD50G21-40NT-A1.pdf
+ *
+ */
+namespace FTDI_LCD_800x480 {
+ const int Vsync0 = 0;
+ const int Vsync1 = 13;
+ const int Voffset = 16;
+ const int Vcycle = 525;
+ const int Hsync0 = 0;
+ const int Hsync1 = 40;
+ const int Hoffset = 88;
+ const int Hcycle = 928;
+ const int Hsize = 800;
+ const int Vsize = 480;
+ const int Pclkpol = 1;
+ const int Swizzle = 0;
+ const int Pclk = 2;
+ const int Clksel = 0x45;
+
+ const uint32_t default_transform_a = 0x0000012B;
+ const uint32_t default_transform_b = 0xFFFF7BFC;
+ const uint32_t default_transform_c = 0x01F2443A;
+ const uint32_t default_transform_d = 0xFFFF25ED;
+ const uint32_t default_transform_e = 0x000000F9;
+ const uint32_t default_transform_f = 0x033F61DA;
+}
+
+// HOST COMMANDS
+
+namespace FTDI {
+ const uint8_t ACTIVE = 0x00;
+ const uint8_t STANDBY = 0x41;
+ const uint8_t SLEEP = 0x42;
+ const uint8_t PWRDOWN = 0x50;
+ const uint8_t CLKEXT = 0x44;
+ const uint8_t CLKINT = 0x48;
+ const uint8_t CORESET = 0x68;
+}
+namespace FT800 {
+ const uint8_t CLK48M = 0x62;
+ const uint8_t CLK36M = 0x61;
+}
+namespace FT810 {
+ const uint8_t CLKSEL = 0x61;
+}
+
+// DISPLAY LIST COMMANDS
+
+namespace FTDI {
+ const uint32_t ALPHA_FUNC = 0x09000000;
+
+ const uint32_t ALPHA_FUNC_NEVER = 0x00000000;
+ const uint32_t ALPHA_FUNC_LESS = 0x00010000;
+ const uint32_t ALPHA_FUNC_LEQUAL = 0x00020000;
+ const uint32_t ALPHA_FUNC_GREATER = 0x00030000;
+ const uint32_t ALPHA_FUNC_GEQUAL = 0x00040000;
+ const uint32_t ALPHA_FUNC_EQUAL = 0x00050000;
+ const uint32_t ALPHA_FUNC_NOTEQUAL = 0x00060000;
+ const uint32_t ALPHA_FUNC_ALWAYS = 0x00070000;
+
+ const uint32_t BEGIN = 0x1F000000;
+
+ const uint32_t BEGIN_BITMAPS = 0x00000001;
+ const uint32_t BEGIN_POINTS = 0x00000002;
+ const uint32_t BEGIN_LINES = 0x00000003;
+ const uint32_t BEGIN_LINE_STRIP = 0x00000004;
+ const uint32_t BEGIN_STRIP_R = 0x00000005;
+ const uint32_t BEGIN_STRIP_L = 0x00000006;
+ const uint32_t BEGIN_STRIP_A = 0x00000007;
+ const uint32_t BEGIN_STRIP_B = 0x00000008;
+ const uint32_t BEGIN_STRIP_RECTS = 0x00000009;
+
+ const uint32_t BITMAP_HANDLE = 0x05000000;
+
+ const uint32_t BITMAP_LAYOUT = 0x07000000;
+
+ const uint32_t BITMAP_LAYOUT_ARGB1555 = 0x00000000;
+ const uint32_t BITMAP_LAYOUT_L1 = 0x00080000;
+ const uint32_t BITMAP_LAYOUT_L4 = 0x00100000;
+ const uint32_t BITMAP_LAYOUT_L8 = 0x00180000;
+ const uint32_t BITMAP_LAYOUT_RGB332 = 0x00200000;
+ const uint32_t BITMAP_LAYOUT_ARGB2 = 0x00280000;
+ const uint32_t BITMAP_LAYOUT_ARGB4 = 0x00300000;
+ const uint32_t BITMAP_LAYOUT_RGB565 = 0x00380000;
+ const uint32_t BITMAP_LAYOUT_PALETTED = 0x00400000;
+ const uint32_t BITMAP_LAYOUT_TEXT8X8 = 0x00480000;
+ const uint32_t BITMAP_LAYOUT_TEXTVGA = 0x00500000;
+ const uint32_t BITMAP_LAYOUT_BARGRAPH = 0x00580000;
+
+ const uint8_t ARGB1555 = 0x00;
+ const uint8_t L1 = 0x01;
+ const uint8_t L4 = 0x02;
+ const uint8_t L8 = 0x03;
+ const uint8_t RGB332 = 0x04;
+ const uint8_t ARGB2 = 0x05;
+ const uint8_t ARGB4 = 0x06;
+ const uint8_t RGB565 = 0x07;
+ const uint8_t PALETTED = 0x08;
+ const uint8_t TEXT8X8 = 0x09;
+ const uint8_t TEXTVGA = 0x0A;
+ const uint8_t BARGRAPH = 0x0B;
+
+ const uint32_t BITMAP_SIZE = 0x08000000;
+
+ const uint8_t NEAREST = 0x00;
+ const uint8_t BILINEAR = 0x01;
+ const uint8_t BORDER = 0x00;
+ const uint8_t REPEAT = 0x01;
+
+ const uint32_t BITMAP_SOURCE = 0x01000000;
+
+ const uint32_t BITMAP_TRANSFORM_A = 0x15000000;
+
+ const uint32_t BITMAP_TRANSFORM_B = 0x16000000;
+
+ const uint32_t BITMAP_TRANSFORM_C = 0x17000000;
+
+ const uint32_t BITMAP_TRANSFORM_D = 0x18000000;
+
+ const uint32_t BITMAP_TRANSFORM_E = 0x19000000;
+
+ const uint32_t BITMAP_TRANSFORM_F = 0x1A000000;
+
+ const uint32_t BLEND_FUNC = 0x0B000000;
+
+ const uint32_t BLEND_FUNC_SRC_ZERO = 0x00000000;
+ const uint32_t BLEND_FUNC_SRC_ONE = 0x00000008;
+ const uint32_t BLEND_FUNC_SRC_SRC_ALPHA = 0x00000010;
+ const uint32_t BLEND_FUNC_SRC_DST_ALPHA = 0x00000018;
+ const uint32_t BLEND_FUNC_SRC_ONE_MINUS_SRC_ALPHA = 0x00000020;
+ const uint32_t BLEND_FUNC_SRC_ONE_MINUS_DST_ALPHA = 0x00000028;
+
+ const uint32_t BLEND_FUNC_DST_ZERO = 0x00000000;
+ const uint32_t BLEND_FUNC_DST_ONE = 0x00000001;
+ const uint32_t BLEND_FUNC_DST_SRC_ALPHA = 0x00000002;
+ const uint32_t BLEND_FUNC_DST_DST_ALPHA = 0x00000003;
+ const uint32_t BLEND_FUNC_DST_ONE_MINUS_SRC_ALPHA = 0x00000004;
+ const uint32_t BLEND_FUNC_DST_ONE_MINUS_DST_ALPHA = 0x00000005;
+
+ const uint32_t CALL = 0x1D000000;
+
+ const uint32_t CELL = 0x06000000;
+
+ const uint32_t CLEAR = 0x26000000;
+
+ const uint32_t CLEAR_COLOR_BUFFER = 0x00000004;
+ const uint32_t CLEAR_STENCIL_BUFFER = 0x00000002;
+ const uint32_t CLEAR_TAG_BUFFER = 0x00000001;
+
+ const uint32_t CLEAR_COLOR_A = 0x0F000000;
+
+ const uint32_t CLEAR_COLOR_RGB = 0x02000000;
+
+ const uint32_t CLEAR_STENCIL = 0x11000000;
+
+ const uint32_t CLEAR_TAG = 0x12000000;
+
+ const uint32_t COLOR_A = 0x10000000;
+
+ const uint32_t COLOR_MASK = 0x20000000;
+
+ const uint32_t COLOR_MASK_RED = 0x00000008;
+ const uint32_t COLOR_MASK_GRN = 0x00000004;
+ const uint32_t COLOR_MASK_BLU = 0x00000002;
+ const uint32_t COLOR_MASK_ALPHA = 0x00000001;
+
+ const uint32_t COLOR_RGB = 0x04000000;
+
+ const uint32_t DL_DISPLAY = 0x00000000;
+
+ const uint32_t END = 0x21000000;
+
+ const uint32_t JUMP = 0x1E000000;
+
+ const uint32_t LINE_WIDTH = 0x0E000000;
+
+ const uint32_t MACRO = 0x25000000;
+
+ const uint32_t POINT_SIZE = 0x0D000000;
+
+ const uint32_t RESTORE_CONTEXT = 0x23000000;
+
+ const uint32_t RETURN = 0x24000000;
+
+ const uint32_t SAVE_CONTEXT = 0x22000000;
+
+ const uint32_t SCISSOR_SIZE = 0x1C000000;
+
+ const uint32_t SCISSOR_XY = 0x1B000000;
+
+ const uint32_t STENCIL_FUNC = 0x0A000000;
+
+ const uint32_t STENCIL_FUNC_NEVER = 0x00000000;
+ const uint32_t STENCIL_FUNC_LESS = 0x00010000;
+ const uint32_t STENCIL_FUNC_LEQUAL = 0x00020000;
+ const uint32_t STENCIL_FUNC_GREATER = 0x00030000;
+ const uint32_t STENCIL_FUNC_GEQUAL = 0x00040000;
+ const uint32_t STENCIL_FUNC_EQUAL = 0x00050000;
+ const uint32_t STENCIL_FUNC_NOTEQUAL = 0x00060000;
+ const uint32_t STENCIL_FUNC_ALWAYS = 0x00070000;
+
+ const uint32_t STENCIL_MASK = 0x13000000;
+
+ const uint32_t STENCIL_OP = 0x0C000000;
+
+ const uint32_t STENCIL_OP_PASS_ZERO = 0x00000000;
+ const uint32_t STENCIL_OP_PASS_KEEP = 0x00000001;
+ const uint32_t STENCIL_OP_PASS_REPLACE = 0x00000002;
+ const uint32_t STENCIL_OP_PASS_INCR = 0x00000003;
+ const uint32_t STENCIL_OP_PASS_DECR = 0x00000004;
+ const uint32_t STENCIL_OP_PASS_INVERT = 0x00000005;
+
+ const uint32_t STENCIL_OP_FAIL_ZERO = 0x00000000;
+ const uint32_t STENCIL_OP_FAIL_KEEP = 0x00000008;
+ const uint32_t STENCIL_OP_FAIL_REPLACE = 0x00000010;
+ const uint32_t STENCIL_OP_FAIL_INCR = 0x00000018;
+ const uint32_t STENCIL_OP_FAIL_DECR = 0x00000020;
+ const uint32_t STENCIL_OP_FAIL_INVERT = 0x00000028;
+
+ const uint32_t TAG = 0x03000000;
+
+ const uint32_t TAG_MASK = 0x14000000;
+
+ const uint32_t VERTEX2F = 0x40000000;
+
+ const uint32_t VERTEX2II = 0x80000000;
+}
+
+// CO-PROCESSOR ENGINE COMMANDS
+namespace FTDI {
+ const uint32_t CMD_DLSTART = 0xFFFFFF00;
+ const uint32_t CMD_SWAP = 0xFFFFFF01;
+ const uint32_t CMD_COLDSTART = 0xFFFFFF32;
+ const uint32_t CMD_INTERRUPT = 0xFFFFFF02;
+ const uint32_t CMD_APPEND = 0xFFFFFF1E;
+ const uint32_t CMD_REGREAD = 0xFFFFFF19;
+ const uint32_t CMD_MEMWRITE = 0xFFFFFF1A;
+ const uint32_t CMD_INFLATE = 0xFFFFFF22;
+ const uint32_t CMD_LOADIMAGE = 0xFFFFFF24;
+ const uint32_t CMD_MEMCRC = 0xFFFFFF18;
+ const uint32_t CMD_MEMZERO = 0xFFFFFF1C;
+ const uint32_t CMD_MEMSET = 0xFFFFFF1B;
+ const uint32_t CMD_MEMCPY = 0xFFFFFF1D;
+ const uint32_t CMD_BUTTON = 0xFFFFFF0D;
+ const uint32_t CMD_CLOCK = 0xFFFFFF14;
+ const uint32_t CMD_FGCOLOR = 0xFFFFFF0A;
+ const uint32_t CMD_BGCOLOR = 0xFFFFFF09;
+ const uint32_t CMD_GRADCOLOR = 0xFFFFFF34;
+ const uint32_t CMD_GAUGE = 0xFFFFFF13;
+ const uint32_t CMD_GRADIENT = 0xFFFFFF0B;
+ const uint32_t CMD_KEYS = 0xFFFFFF0E;
+ const uint32_t CMD_PROGRESS = 0xFFFFFF0F;
+ const uint32_t CMD_SCROLLBAR = 0xFFFFFF11;
+ const uint32_t CMD_SLIDER = 0xFFFFFF10;
+ const uint32_t CMD_DIAL = 0xFFFFFF2D;
+ const uint32_t CMD_TOGGLE = 0xFFFFFF12;
+ const uint32_t CMD_TEXT = 0xFFFFFF0C;
+ const uint32_t CMD_NUMBER = 0xFFFFFF2E;
+ const uint32_t CMD_LOADIDENTITY = 0xFFFFFF26;
+ const uint32_t CMD_SETMATRIX = 0xFFFFFF2A;
+ const uint32_t CMD_GETMATRIX = 0xFFFFFF33;
+ const uint32_t CMD_GETPTR = 0xFFFFFF23;
+ const uint32_t CMD_GETPROPS = 0xFFFFFF25;
+ const uint32_t CMD_SCALE = 0xFFFFFF28;
+ const uint32_t CMD_ROTATE = 0xFFFFFF29;
+ const uint32_t CMD_TRANSLATE = 0xFFFFFF27;
+ const uint32_t CMD_CALIBRATE = 0xFFFFFF15;
+ const uint32_t CMD_SPINNER = 0xFFFFFF16;
+ const uint32_t CMD_SCREENSAVER = 0xFFFFFF2F;
+ const uint32_t CMD_SKETCH = 0xFFFFFF30;
+ const uint32_t CMD_STOP = 0xFFFFFF17;
+ const uint32_t CMD_SETFONT = 0xFFFFFF2B;
+ const uint32_t CMD_TRACK = 0xFFFFFF2C;
+ const uint32_t CMD_SNAPSHOT = 0xFFFFFF1F;
+ const uint32_t CMD_LOGO = 0xFFFFFF31;
+}
+
+// If IS_FT800 is defined, then copy the FT800 namespace into the FTDI namespace
+// If IS_FT810 is defined, then copy the FT810 namespace into the FTDI namespace
+
+#if defined(IS_FT800)
+namespace FTDI {
+ using namespace FT800;
+}
+#elif defined(IS_FT810)
+namespace FTDI {
+ using namespace FT810;
+}
+#endif
+
+#endif // _AO_FT810_H
+
+
+
+
+
diff --git a/Marlin/AO_FT810_Functions.h b/Marlin/AO_FT810_Functions.h
new file mode 100644
index 000000000..afe2eb32d
--- /dev/null
+++ b/Marlin/AO_FT810_Functions.h
@@ -0,0 +1,739 @@
+/*********************
+ * FT810_Functions.h *
+ *********************/
+
+
+/****************************************************************************
+ * Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * To view a copy of the GNU General Public License, go to the following *
+ * location: . *
+ ****************************************************************************/
+
+ /****************************************************************************
+ * FUNCTION MAP *
+ * *
+ * SPI and FT800/810 Commands *
+ * *
+ * CLCD::spiSelect() Set CS line to 0 *
+ * CLCD::spiDeselect() Set CS Line to 1 *
+ * CLCD::Reset() Toggle FT800/810 Power Down Line 50 ms *
+ * CLCD::spiInit() Configure I/O Lines for SPI *
+ * CLCD::spiTransfer() Send/Receive 1 SPI Byte *
+ * CLCD::Init() Set FT800/810 Registers *
+ * CLCD::Enable() Turn On FT800/810 PCLK *
+ * CLCD::Disable() Turn Off FT8880/810 PCLK *
+ * CLCD::Set_Backlight() Set LCD Backlight Level *
+ * *
+ * MEMORY READ FUNCTIONS *
+ * *
+ * CLCD::Mem_ReadAddr() Send 32-Bit Address *
+ * CLCD::Mem_Read8() Read 1 Byte *
+ * CLCD::Mem_Read16() Read 2 Bytes *
+ * CLCD::Mem_Read32() Read 4 Bytes *
+ * *
+ * MEMORY WRITE FUNCTIONS *
+ * *
+ * CLCD::Mem_WriteAddr() Send 24-Bit Address *
+ * CLCD::Mem_Write8() Write 1 Byte *
+ * CLCD::Mem_Write16() Write 2 Bytes *
+ * CLCD::Mem_Write32() Write 4 Bytes *
+ * *
+ * HOST COMMAND FUNCTION *
+ * *
+ * CLCD::Host_Cmd() Send 24-Bit Host Command *
+ * *
+ * COMMAND BUFFER FUNCTIONS *
+ * *
+ * CLCD::Cmd() Send 32-Bit Value(4 Bytes)CMD Buffer *
+ * CLCD::Cmd() Send Data Structure with 32-Bit Cmd *
+ * CLCD::Cmd_Str() Send Text String in 32-Bit Multiples *
+
+ * *
+ * FT800/810 GRAPHIC COMMANDS *
+ * *
+ * class CLCD:CommandFifo {} Class to control Cmd FIFO *
+
+ * Fifo::Start() Wait for CP finish - Set FIFO Ptr *
+ * Fifo::Execute() Set REG_CMD_WRITE and start CP *
+ * Fifo::Reset() Set Cmd Buffer Pointers to 0 *
+ *
+ * Fifo::Cmd_Clear_Color() Set Clear Screen Color *
+ * Fifo::Cmd_Clear() Clear Color-Stencil-Tag Buffer(s) *
+ * Fifo::Cmd_Color() Set Current Color *
+ * Fifo::Cmd_Set_Foreground_Color Set Graphic Item Foreground Color *
+ * Fifo::Cmd_Set_Background_Color Set Graphic Item Background Color *
+ * Fifo::Cmd_Bitmap_Source() Set RAM Address of Bitmap Data *
+ * Fifo::Cmd_Bitmap_Layout() Configure Bitmap Format and Layout *
+ * Fifo::Cmd_Bitmap_Size() Set Bitmap Dimensions *
+ * Fifo::Cmd_Bitmap_Handle() Assign Handle ID to a Bitmap *
+ * Fifo::Cmd_Begin() Begin Drawing a Primative *
+ * Fifo::Cmd_Mem_Copy() Copy a Block of Memory *
+ * Fifo::Cmd_Append() Append Commands to Current DL *
+ * Fifo::Cmd_Gradient_Color() Set 3D Button Highlight Color *
+ * Fifo::Cmd_Vertex_2II() Set Coordinates of Graphics Primative *
+ * Fifo::Cmd_Draw_Button() Draw Button with Bulk Write *
+ * Fifo::Cmd_Draw_Text() Draw Text with Bulk Write *
+ *
+ *
+ */
+
+
+ /**************************************************
+ * RAM_G Graphics RAM Allocation *
+ * *
+ * Address Use *
+ * *
+ * 8000 Extruder Bitmap *
+ * 8100 Bed Heat Bitmap *
+ * 8200 Fan Bitmap *
+ * 8300 Thumb Drive Symbol Bitmap *
+ * 3E000 Static DL Space (FT800) *
+ * FE000 Static DL Space (FT810) *
+ **************************************************/
+
+#ifndef _AO_FT810_FUNC_H
+#define _AO_FT810_FUNC_H
+
+#if defined(IS_FT800)
+ #define DL_CACHE_START 0x03E000
+#else
+ #define DL_CACHE_START 0x0FE000
+#endif
+
+#if defined(LCD_800x480)
+using namespace FTDI_LCD_800x480;
+#else
+using namespace FTDI_LCD_480x272;
+#endif
+
+using namespace FTDI;
+
+typedef const __FlashStringHelper *progmem_str;
+
+#define FORCEDINLINE __attribute__((always_inline))
+
+class CLCD {
+ private:
+ static void spiInit (void);
+ static void spiSelect (void);
+ static void spiDeselect (void);
+ static uint8_t spiTransfer (uint8_t spiOutByte);
+ static void Mem_ReadAddr (uint32_t Reg_Address);
+ static void Mem_WriteAddr (uint32_t Reg_Address);
+ static void Mem_Read_Bulk (uint32_t Reg_Address, uint8_t *Data, uint16_t Len);
+ static void Mem_Write_Bulk (uint32_t Reg_Address, const void *Data, uint16_t Len, uint8_t Padding = 0);
+ static void Mem_Write_Bulk (uint32_t Reg_Address, progmem_str Str, uint16_t Len, uint8_t Padding = 0);
+
+ public:
+ static uint8_t Mem_Read8 (uint32_t Reg_Address);
+ static uint16_t Mem_Read16 (uint32_t Reg_Address);
+ static uint32_t Mem_Read32 (uint32_t Reg_Address);
+ static void Mem_Write8 (uint32_t Reg_Address, uint8_t W_Data);
+ static void Mem_Write16 (uint32_t Reg_Address, uint16_t W_Data);
+ static void Mem_Write32 (uint32_t Reg_Address, uint32_t W_Data);
+
+ static inline uint32_t pack_rgb(uint8_t r, uint8_t g, uint8_t b);
+
+ public:
+ typedef struct {
+ const uint8_t format;
+ const uint16_t linestride;
+ const uint8_t filter;
+ const uint8_t wrapx;
+ const uint8_t wrapy;
+ const uint32_t RAMG_addr;
+ const uint16_t width;
+ const uint16_t height;
+ } bitmap_info_t;
+
+ class CommandFifo {
+ protected:
+ static uint32_t getRegCmdWrite();
+ static uint32_t getRegCmdRead();
+
+ #if defined(IS_FT800)
+ uint32_t command_write_ptr;
+ template void _write_unaligned(T data, uint16_t len);
+ #else
+ uint32_t getRegCmdBSpace();
+ #endif
+ public:
+
+ template void write(T data, uint16_t len);
+
+ public:
+ static void Reset (void);
+ static bool Is_Idle();
+ static void Wait_Until_Idle();
+
+ void Cmd_Start(void);
+ void Cmd_Execute(void);
+
+ void Cmd (uint32_t cmd32);
+ void Cmd (void* data, uint16_t len);
+ void Cmd_Str (char* data);
+ void Cmd_Str (progmem_str data);
+ void Cmd_Clear_Color (uint32_t rgb);
+ void Cmd_Clear (bool Clr, bool Stl, bool Tag);
+ void Cmd_Color (uint32_t rgb);
+ void Cmd_Set_Foreground_Color (uint32_t rgb);
+ void Cmd_Set_Background_Color (uint32_t rgb);
+ void Cmd_Set_Tag (uint8_t Tag);
+ void Cmd_Bitmap_Source (uint32_t RAM_G_Addr);
+
+ // The following functions *must* be inlined since we are relying on the compiler to do
+ // substitution of the constants from the data structure rather than actually storing
+ // it in PROGMEM (which would fail, since we are not using pgm_read_near to read them).
+ // Plus, by inlining, all the equations are evaluated at compile-time as everything
+ // should be a constant.
+
+ FORCEDINLINE void Cmd_Bitmap_Source (const bitmap_info_t& info) {Cmd_Bitmap_Source (info.RAMG_addr);};
+ FORCEDINLINE void Cmd_Bitmap_Layout (const bitmap_info_t& info) {Cmd_Bitmap_Layout (info.format, info.linestride, info.height);};
+ FORCEDINLINE void Cmd_Bitmap_Size(const bitmap_info_t& info) {Cmd_Bitmap_Size (info.filter, info.wrapx, info.wrapy, info.width, info.height);}
+ FORCEDINLINE void Cmd_Draw_Button_Icon(int16_t x, int16_t y, int16_t w, int16_t h, const bitmap_info_t& info, const float scale = 1) {
+ Cmd_Begin(BEGIN_BITMAPS);
+ if(scale != 1) {
+ Cmd(BITMAP_TRANSFORM_A | uint32_t(float(256)/scale) & 0xFFFF);
+ Cmd(BITMAP_TRANSFORM_E | uint32_t(float(256)/scale) & 0xFFFF);
+ }
+ Cmd_Bitmap_Size(info.filter, info.wrapx, info.wrapy, info.width*scale, info.height*scale);
+ Cmd_Vertex_2F((x + w/2 - info.width*scale/2)*16, (y + h/2 - info.height*scale/2)*16);
+ if(scale != 1) {
+ Cmd(BITMAP_TRANSFORM_A | 256);
+ Cmd(BITMAP_TRANSFORM_E | 256);
+ }
+ }
+ template FORCEDINLINE void Cmd_Draw_Button_Text(int16_t x, int16_t y, int16_t w, int16_t h, T text, int16_t font) {
+ Cmd_Draw_Text(x + w/2, y + h/2, text, font, OPT_CENTER);
+ }
+
+ void Cmd_Bitmap_Layout (uint8_t format, uint16_t linestride, uint16_t height);
+ void Cmd_Bitmap_Size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height);
+ void Cmd_Bitmap_Handle (uint16_t Handle);
+ void Cmd_Begin (uint32_t Primitive);
+ void Cmd_Vertex_2F (uint16_t X_Coord, uint16_t Y_Coord);
+ void Cmd_Vertex_2II (uint16_t X_Coord, uint16_t Y_Coord, uint8_t B_Handle, uint8_t Cell);
+
+ template void Cmd_Draw_Button(int16_t x, int16_t y, int16_t w, int16_t h, T text, int16_t font, uint16_t option);
+ template void Cmd_Draw_Text(int16_t x, int16_t y, T text, int16_t font, uint16_t options);
+
+ void Cmd_Draw_Clock (int16_t x, int16_t y, int16_t r, uint16_t option, int16_t h, int16_t m, int16_t s, int16_t ms);
+ void Cmd_Draw_Progress_Bar (int16_t x, int16_t y, int16_t w, int16_t h, int16_t val, int16_t range);
+ void Cmd_Draw_Slider (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
+ void Cmd_Mem_Cpy (uint32_t dst, uint32_t src, uint32_t size);
+ void Cmd_Append (uint32_t ptr, uint32_t size);
+ };
+
+ class DLCache {
+ private:
+ static uint16_t dl_free;
+ uint16_t dl_addr = 0;
+ uint16_t dl_size = 0;
+ public:
+ bool hasData();
+ void store();
+ void append();
+ };
+
+ public:
+ static void Init (void);
+ static void Turn_On_Backlight (void);
+ static void Reset (void);
+ static void Test_Pulse(void);
+ static void Enable (void);
+ static void Disable (void);
+ static void Set_Backlight (uint16_t Freq, uint8_t Duty);
+ static void Host_Cmd (unsigned char Host_Command, unsigned char Byte2);
+
+ static void Get_Font_Metrics(uint8_t font, struct FontMetrics &fm);
+ static void Flash_Write_RGB332_Bitmap(uint32_t Mem_Address, const unsigned char* pRGB332_Array, uint16_t Num_Bytes);
+
+ static uint8_t Get_Tag() {return Mem_Read8(REG_TOUCH_TAG);}
+};
+
+/********************************* FT800/810 Commands *********************************/
+
+#define MULTIPLE_OF_4(val) ((((val)+3)>>2)<<2)
+
+void CLCD::Enable (void) {
+ Mem_Write8(REG_PCLK, Pclk);
+}
+
+void CLCD::Disable (void) {
+ Mem_Write8(REG_PCLK, 0x00);
+}
+
+void CLCD::Set_Backlight (uint16_t Freq, uint8_t Duty) {
+ Mem_Write16(REG_PWM_HZ, Freq);
+ Mem_Write8(REG_PWM_DUTY, Duty);
+}
+
+void CLCD::Turn_On_Backlight (void) {
+ Set_Backlight(0x00FA, 128);
+}
+
+struct FontMetrics {
+ uint8_t char_widths[128];
+ uint32_t font_format;
+ uint32_t font_stride;
+ uint32_t font_width;
+ uint32_t font_height;
+ uint32_t font_ptr;
+};
+
+void CLCD::Get_Font_Metrics(uint8_t font, struct FontMetrics &fm) {
+ Mem_Read_Bulk(ROM_FONT_ADDR + 148 * (font - 16), (uint8_t*) &fm, 148);
+}
+
+// HOST COMMAND FUNCTION
+
+void CLCD::Host_Cmd (unsigned char Host_Command, unsigned char Byte2) { // Sends 24-Bit Host Command to LCD
+ if(Host_Command != ACTIVE) {
+ Host_Command |= 0x40;
+ }
+
+ spiSelect();
+
+ spiTransfer(Host_Command); // Write Byte 1
+
+ spiTransfer(Byte2); // Write Byte 2
+
+ spiTransfer(0x00); // Write Byte 3
+
+ spiDeselect();
+}
+
+void CLCD::Flash_Write_RGB332_Bitmap(uint32_t Mem_Address, const unsigned char* pRGB332_Array, uint16_t Num_Bytes)
+{
+ unsigned char Flash_Byte;
+
+ for(unsigned int i = 0; i < Num_Bytes; i++) {
+ Flash_Byte = pgm_read_byte_near(pRGB332_Array + i);
+
+ Mem_Write8((Mem_Address + i), Flash_Byte);
+ }
+}
+
+uint8_t Device_ID;
+
+void CLCD::Init (void) {
+ spiInit(); // Set Up I/O Lines for SPI and FT800/810 Control
+ delay(50);
+
+ Reset(); // Power Down the FT800/810 for 50 ms
+ delay(50);
+
+/*
+ * If driving the 4D Systems 4DLCD-FT843 Board, the following Init sequence is needed for its FT800 Driver
+ */
+
+#ifdef IS_FT800 // Use External Crystal and 48 MHz System Clock
+ Host_Cmd(CLKEXT, 0);
+
+ delay(20);
+ Host_Cmd(CLK48M, 0);
+#else
+ Host_Cmd(CLKINT, 0);
+ delay(20);
+ Host_Cmd(CLKSEL, Clksel); // Use Internal RC Oscillator and 48 MHz System Clock
+#endif
+
+ delay(20);
+
+ Host_Cmd(ACTIVE, 0); // Activate the System Clock
+ delay(50);
+
+ delay(400);
+ Device_ID = Mem_Read8(REG_ID); // Read Device ID, Should Be 0x7C;
+ #if defined(UI_FRAMEWORK_DEBUG)
+ if(Device_ID != 0x7C) {
+ #if defined (SERIAL_PROTOCOLLNPAIR)
+ SERIAL_PROTOCOLLNPAIR("Incorrect device ID, should be 7C, got ", Device_ID);
+ #else
+ Serial.print(F("Incorrect device ID, should be 7C, got "));
+ Serial.println(Device_ID, HEX);
+ #endif
+ } else {
+ #if defined (SERIAL_PROTOCOLLNPAIR)
+ SERIAL_PROTOCOLLNPGM("Device is correct ");
+ #else
+ Serial.println(F("Device is correct "));
+ #endif
+ }
+ #endif
+ delay(400);
+
+ Mem_Write8(REG_GPIO, 0x00); // Turn OFF Display Enable (GPIO Bit 7);
+ Mem_Write8(REG_PCLK, 0x00); // Turn OFF LCD PCLK
+ Set_Backlight(0x00FA, 0);
+
+ /*
+ * Configure the FT800/810 Registers
+ */
+
+ Mem_Write16(REG_HCYCLE, Hcycle);
+ Mem_Write16(REG_HOFFSET, Hoffset);
+ Mem_Write16(REG_HSYNC0, Hsync0);
+ Mem_Write16(REG_HSYNC1, Hsync1);
+ Mem_Write16(REG_VCYCLE, Vcycle);
+ Mem_Write16(REG_VOFFSET, Voffset);
+ Mem_Write16(REG_VSYNC0, Vsync0);
+ Mem_Write16(REG_VSYNC1, Vsync1);
+ Mem_Write16(REG_HSIZE, Hsize);
+ Mem_Write16(REG_VSIZE, Vsize);
+ Mem_Write8(REG_SWIZZLE, Swizzle);
+ Mem_Write8(REG_PCLK_POL, Pclkpol);
+ Mem_Write8(REG_CSPREAD, 1);
+
+ #if defined(LCD_PORTRAIT) && defined(LCD_UPSIDE_DOWN)
+ Mem_Write8(REG_ROTATE, 3);
+ #elif defined(LCD_PORTRAIT) && !defined(LCD_UPSIDE_DOWN)
+ Mem_Write8(REG_ROTATE, 2);
+ #elif !defined(LCD_PORTRAIT) && defined(LCD_UPSIDE_DOWN)
+ Mem_Write8(REG_ROTATE, 1);
+ #else !defined(LCD_PORTRAIT) && !defined(LCD_UPSIDE_DOWN)
+ Mem_Write8(REG_ROTATE, 0);
+ #endif
+
+ Mem_Write8(REG_TOUCH_MODE, 0x03); // Configure the Touch Screen
+ Mem_Write8(REG_TOUCH_ADC_MODE, 0x01);
+ Mem_Write8(REG_TOUCH_OVERSAMPLE, 0x0F);
+ Mem_Write16(REG_TOUCH_RZTHRESH, 5000);
+ Mem_Write8(REG_VOL_SOUND, 0x00); // Turn Synthesizer Volume Off
+ Mem_Write8(REG_DLSWAP, 0x02); // Swap on New Frame
+
+ /*
+ * Turn On the Display
+ */
+ #if defined(IS_FT800)
+ Mem_Write8(REG_GPIO_DIR, 0x80); // Turn ON Display Enable
+ Mem_Write8(REG_GPIO, 0x80);
+ #else
+ Mem_Write16(REG_GPIOX_DIR, 1 << 15); // Turn ON Display Enable
+ Mem_Write16(REG_GPIOX, 1 << 15);
+ #endif
+
+ Enable(); // Turns on Clock by setting PCLK Register to 5
+ delay(50);
+
+ CommandFifo::Reset();
+ delay(50);
+
+ // Set Initial Values for Touch Transform Registers
+
+ CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_A, default_transform_a);
+ CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_B, default_transform_b);
+ CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_C, default_transform_c);
+ CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_D, default_transform_d);
+ CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_E, default_transform_e);
+ CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_F, default_transform_f);
+}
+
+/******************* FT800/810 Graphic Commands *********************************/
+
+inline uint32_t CLCD::pack_rgb(uint8_t r, uint8_t g, uint8_t b) {
+ return (uint32_t(r) << 16) | (uint32_t(g) << 8) | uint32_t(b);
+}
+
+void CLCD::CommandFifo::Cmd_Clear_Color (uint32_t rgb) // DL Command - Set Clear Screen Color
+{
+ Cmd(CLEAR_COLOR_RGB | rgb);
+}
+
+void CLCD::CommandFifo::Cmd_Clear (bool Clr, bool Stl, bool Tag) // DL Command - Clear Color-Stencil-Tag Buffer(s)
+{
+ Cmd( CLEAR |
+ (Clr ? 0b00000001 : 0) |
+ (Stl ? 0b00000010 : 0) |
+ (Tag ? 0b00000100 : 0)
+ );
+}
+
+void CLCD::CommandFifo::Cmd_Color (uint32_t rgb) // DL Command - Set Current Color
+{
+ Cmd(COLOR_RGB | rgb);
+}
+
+void CLCD::CommandFifo::Cmd_Set_Foreground_Color (uint32_t rgb) // Co-Processor Command - Set Foreground Color for Widgets
+{
+ Cmd(CMD_FGCOLOR);
+ Cmd(rgb);
+}
+
+void CLCD::CommandFifo::Cmd_Set_Background_Color (uint32_t rgb) // Co-Processor Command - Set Background Color for Widgets
+{
+ Cmd(CMD_BGCOLOR);
+ Cmd(rgb);
+}
+
+void CLCD::CommandFifo::Cmd_Set_Tag (uint8_t Tag)
+{
+ Cmd(TAG | Tag);
+}
+
+void CLCD::CommandFifo::Cmd_Bitmap_Source (uint32_t RAM_G_Addr)
+{
+ Cmd(BITMAP_SOURCE | (RAM_G_Addr & 0x000FFFFF));
+}
+
+void CLCD::CommandFifo::Cmd_Bitmap_Layout (uint8_t format, uint16_t linestride, uint16_t height)
+{
+ Cmd( BITMAP_LAYOUT |
+ (uint32_t(height) << 0) |
+ (uint32_t(linestride) << 9) |
+ (uint32_t(format) << 19)
+ );
+}
+
+void CLCD::CommandFifo::Cmd_Bitmap_Size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height)
+{
+ Cmd( BITMAP_SIZE |
+ (uint32_t(height) << 0) |
+ (uint32_t(width) << 9) |
+ (uint32_t(wrapy) << 18) |
+ (uint32_t(wrapx) << 19) |
+ (uint32_t(filter) << 20)
+ );
+}
+
+void CLCD::CommandFifo::Cmd_Bitmap_Handle (uint16_t Handle)
+{
+ Cmd( BITMAP_HANDLE | Handle);
+}
+
+
+void CLCD::CommandFifo::Cmd_Begin (uint32_t Primitive)
+{
+ Cmd(BEGIN + Primitive);
+}
+
+void CLCD::CommandFifo::Cmd_Vertex_2II (uint16_t X_Coord, uint16_t Y_Coord, uint8_t B_Handle, uint8_t Cell)
+{
+ Cmd( VERTEX2II |
+ (uint32_t(Cell) << 0) |
+ (uint32_t(B_Handle) << 7) |
+ (uint32_t(Y_Coord) << 12) |
+ (uint32_t(X_Coord) << 21)
+ );
+}
+
+void CLCD::CommandFifo::Cmd_Vertex_2F (uint16_t X_Coord, uint16_t Y_Coord)
+{
+ Cmd( VERTEX2F |
+ (uint32_t(Y_Coord) << 0) |
+ (uint32_t(X_Coord) << 15)
+ );
+}
+
+template void CLCD::CommandFifo::Cmd_Draw_Button(int16_t x, int16_t y, int16_t w, int16_t h, T text, int16_t font, uint16_t option)
+{
+ struct {
+ int32_t type = CMD_BUTTON;
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ int16_t font;
+ uint16_t option;
+ } cmd_data;
+
+ cmd_data.x = x;
+ cmd_data.y = y;
+ cmd_data.w = w;
+ cmd_data.h = h;
+ cmd_data.font = font;
+ cmd_data.option = option;
+
+ Cmd( &cmd_data, sizeof(cmd_data) );
+ Cmd_Str(text);
+}
+
+template void CLCD::CommandFifo::Cmd_Draw_Text(int16_t x, int16_t y, T text, int16_t font, uint16_t options)
+{
+ struct {
+ int32_t type = CMD_TEXT;
+ int16_t x;
+ int16_t y;
+ int16_t font;
+ uint16_t options;
+ } cmd_data;
+
+ cmd_data.x = x;
+ cmd_data.y = y;
+ cmd_data.font = font;
+ cmd_data.options = options;
+
+ Cmd( &cmd_data, sizeof(cmd_data) );
+ Cmd_Str(text);
+}
+
+void CLCD::CommandFifo::Cmd_Draw_Clock (int16_t x, int16_t y, int16_t r, uint16_t option, int16_t h, int16_t m, int16_t s, int16_t ms)
+{
+ struct {
+ int32_t type = CMD_CLOCK;
+ int16_t x;
+ int16_t y;
+ int16_t r;
+ uint16_t option;
+ int16_t h;
+ int16_t m;
+ int16_t s;
+ int16_t ms;
+ } cmd_data;
+
+ cmd_data.x = x;
+ cmd_data.y = y;
+ cmd_data.r = r;
+ cmd_data.option = option;
+ cmd_data.h = h;
+ cmd_data.m = m;
+ cmd_data.s = s;
+ cmd_data.ms = ms;
+
+ Cmd( &cmd_data, sizeof(cmd_data) );
+}
+
+void CLCD::CommandFifo::Cmd_Draw_Progress_Bar (int16_t x, int16_t y, int16_t w, int16_t h, int16_t val, int16_t range)
+{
+ struct {
+ int32_t type = CMD_PROGRESS;
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ uint16_t h;
+ uint16_t val;
+ uint16_t range;
+ } cmd_data;
+
+ cmd_data.x = x;
+ cmd_data.y = y;
+ cmd_data.w = w;
+ cmd_data.h = h;
+ cmd_data.val = val;
+ cmd_data.range = range;
+
+ Cmd( &cmd_data, sizeof(cmd_data) );
+}
+
+void CLCD::CommandFifo::Cmd_Draw_Slider (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range)
+{
+ struct {
+ int32_t type = CMD_SLIDER;
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ uint16_t options;
+ uint16_t val;
+ uint16_t range;
+ } cmd_data;
+
+ cmd_data.x = x;
+ cmd_data.y = y;
+ cmd_data.w = w;
+ cmd_data.h = h;
+ cmd_data.options = options;
+ cmd_data.val = val;
+ cmd_data.range = range;
+
+ Cmd( &cmd_data, sizeof(cmd_data) );
+}
+
+void CLCD::CommandFifo::Cmd_Mem_Cpy (uint32_t dst, uint32_t src, uint32_t size)
+{
+ struct {
+ uint32_t type = CMD_MEMCPY;
+ uint32_t dst;
+ uint32_t src;
+ uint32_t size;
+ } cmd_data;
+
+ cmd_data.dst = dst;
+ cmd_data.src = src;
+ cmd_data.size = size;
+
+ Cmd( &cmd_data, sizeof(cmd_data) );
+}
+
+void CLCD::CommandFifo::Cmd_Append (uint32_t ptr, uint32_t size)
+{
+ struct {
+ uint32_t type = CMD_APPEND;
+ uint32_t ptr;
+ uint32_t size;
+ } cmd_data;
+
+ cmd_data.ptr = ptr;
+ cmd_data.size = size;
+
+ Cmd( &cmd_data, sizeof(cmd_data) );
+}
+
+/******************* DISPLAY LIST CACHE MANAGEMENT ************************/
+
+/* The Display List Cache mechanism stores the display list corresponding
+ * to a menu into RAM_G so that on subsequent calls drawing the menu does
+ * not require as much SPI traffic. Dynamic content, such as indicators,
+ * should not be cached.
+ *
+ * The DLCache can be used like so:
+ *
+ * void some_function() {
+ * static CLCD::DLCache dlcache;
+ *
+ * if(dlcache.hasData()) {
+ * dlcache.append();
+ * } else {
+ * // Add stuff to the DL
+ * dlcache.store();
+ * }
+ */
+
+uint16_t CLCD::DLCache::dl_free = DL_CACHE_START;
+
+bool CLCD::DLCache::hasData() {
+ return dl_addr != 0;
+}
+
+void CLCD::DLCache::store() {
+ while(!CommandFifo::Is_Idle());
+
+ dl_size = Mem_Read32(REG_CMD_DL) & 0x07FF;
+ dl_addr = dl_free;
+
+ if((dl_addr + dl_size) > (1024*1024)) {
+ // Not enough memory to cache the display list.
+ dl_addr = 0;
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd_Mem_Cpy(RAM_G + dl_addr, RAM_DL, dl_size);
+ cmd.Cmd_Execute();
+ dl_free += dl_size;
+ }
+}
+
+void CLCD::DLCache::append() {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd_Append(RAM_G + dl_addr, dl_size);
+ cmd.Cmd_Execute();
+}
+
+#endif // _AO_FT810_FUNC_H
+
+
+
+
+
diff --git a/Marlin/AO_FT810_Pins.h b/Marlin/AO_FT810_Pins.h
new file mode 100644
index 000000000..d21642892
--- /dev/null
+++ b/Marlin/AO_FT810_Pins.h
@@ -0,0 +1,53 @@
+/**
+ * Pins for the Aleph Objects Color LCD Touchscreen.
+ *
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#if defined(LULZBOT_Quiver_TAZ7_CLCD) // ARCHIM J20 HEADER +3.3V Pin-24 GND Pin-23
+ #define CLCD_BB_SPI_CS 99 // PB6 J20 Pin-9
+ #define CLCD_BB_SPI_SCLK 95 // PB0 J20 Pin-6
+ #define CLCD_BB_SPI_MOSI 94 // PB1 J20 Pin-5
+ #define CLCD_BB_SPI_MISO 101 // PB5 J20 Pin-10
+ #define CLCD_MOD_RESET 93 // PB2 J20 Pin-8
+#endif
+
+#if defined(LULZBOT_Gladiola_Mini_CLCD) // MINI RAMBO P1 HEADER +5V Pin-10 GND Pin-9
+ #define CLCD_BB_SPI_SCLK 71 // PG3 P1 Pin-8
+ #define CLCD_BB_SPI_MOSI 85 // PH7 P1 Pin-7
+ #define CLCD_BB_SPI_CS 70 // PG4 P1 Pin-6
+ #define CLCD_MOD_RESET 19 // PD2 P1 Pin-5
+ #define CLCD_BB_SPI_MISO 82 // PD5 P1 Pin-4
+ #define CLCD_AUX_0 18 // PD3 P1 Pin-3
+ #define CLCD_AUX_1 9 // PH6 P1 Pin-2
+ #define CLCD_AUX_2 84 // PH2 P1 Pin-1
+#endif
+
+#if defined(LULZBOT_Hibiscus_Mini2_CLCD) // EINSY P1 HEADER +5V Pin-1 GND Pin-2
+ #define CLCD_BB_SPI_SCLK 71 // PG3 P1 Pin-3
+ #define CLCD_BB_SPI_MOSI 85 // PH7 P1 Pin-4
+ #define CLCD_BB_SPI_CS 70 // PG4 P1 Pin-5
+ #define CLCD_MOD_RESET 19 // PD2 P1 Pin-6
+ #define CLCD_BB_SPI_MISO 82 // PD5 P1 Pin-7
+ #define CLCD_AUX_0 18 // PD3 P1 Pin-8
+ #define CLCD_AUX_1 9 // PH6 P1 Pin-9
+ #define CLCD_AUX_2 84 // PH2 P1 Pin-10
+#endif
\ No newline at end of file
diff --git a/Marlin/AO_FT810_SPI.h b/Marlin/AO_FT810_SPI.h
new file mode 100644
index 000000000..b2c67adfe
--- /dev/null
+++ b/Marlin/AO_FT810_SPI.h
@@ -0,0 +1,387 @@
+/*********************
+ * FT810_SPI.h *
+ *********************/
+
+
+/****************************************************************************
+ * Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * To view a copy of the GNU General Public License, go to the following *
+ * location: . *
+ ****************************************************************************/
+#ifndef _AO_FT810_SPI_H
+#define _AO_FT810_SPI_H
+
+#if defined(PIN_DIR_OUT)
+ // If SET_OUTPUT is defined, then map Marlin routines to those
+ #define SET_OUTPUT PIN_DIR_OUT
+ #define SET_INPUT_PULLUP(a) _PIN_DIR_IN(a); _PIN_HIGH(a);
+ #define SET_INPUT PIN_DIR_IN
+ #define WRITE SET_PIN
+ #define READ GET_PIN
+#endif
+
+/********************************* SPI Functions *********************************/
+
+void CLCD::spiInit (void) {
+#if defined(USE_ARDUINO_HW_SPI)
+ SPI.begin();
+ SPI.beginTransaction(LCDsettings);
+#else
+ SET_OUTPUT(CLCD_MOD_RESET); // CLCD_MOD_RST - Module Reset, not SPI
+ WRITE(CLCD_MOD_RESET, 1);
+
+ SET_OUTPUT(CLCD_BB_SPI_MOSI); // CLCD_MOSI
+ WRITE(CLCD_BB_SPI_MOSI, 1);
+
+ SET_OUTPUT(CLCD_BB_SPI_SCLK); // CLCD_SCLK
+ WRITE(CLCD_BB_SPI_SCLK, 0);
+
+ SET_OUTPUT(CLCD_BB_SPI_CS); // CLCD_CS
+ WRITE(CLCD_BB_SPI_CS, 1);
+
+ SET_INPUT_PULLUP(CLCD_BB_SPI_MISO); // CLCD_MISO
+
+ delay(50);
+#endif
+}
+
+void CLCD::spiSelect (void) { // CLCD Bitbanged SPI - Chip Select
+ WRITE(CLCD_BB_SPI_CS, 0);
+}
+
+
+void CLCD::spiDeselect (void) { // CLCD Bitbanged SPI - Chip Deselect
+ WRITE(CLCD_BB_SPI_CS, 1);
+}
+
+void CLCD::Reset (void) {
+ WRITE(CLCD_MOD_RESET, 0);
+ delay(50);
+ WRITE(CLCD_MOD_RESET, 1);
+}
+
+void CLCD::Test_Pulse(void)
+{
+ WRITE(CLCD_AUX_0, 1);
+ delayMicroseconds(10);
+ WRITE(CLCD_AUX_0, 0);
+}
+
+uint8_t CLCD::spiTransfer (uint8_t spiOutByte) {
+#ifdef IS_ARDUINO
+ SPI.transfer(spiOutByte);
+#else
+
+ uint8_t spiIndex = 0x80;
+ uint8_t spiInByte = 0;
+ uint8_t k;
+
+ for(k = 0; k <8; k++) { // Output and Read each bit of spiOutByte and spiInByte
+ if(spiOutByte & spiIndex) { // Output MOSI Bit
+ WRITE(CLCD_BB_SPI_MOSI, 1);
+ }
+ else {
+ WRITE(CLCD_BB_SPI_MOSI, 0);
+ }
+ WRITE(CLCD_BB_SPI_SCLK, 1); // Pulse Clock
+ WRITE(CLCD_BB_SPI_SCLK, 0);
+
+ if(READ(CLCD_BB_SPI_MISO)) {
+ spiInByte |= spiIndex;
+ }
+
+ spiIndex >>= 1;
+ }
+ return spiInByte;
+#endif
+}
+
+// MEMORY READ FUNCTIONS
+
+void CLCD::Mem_ReadAddr (uint32_t Reg_Address) { // Write 4-Byte Address
+ CLCD::spiTransfer((Reg_Address >> 16) & 0x3F); // Address [21:16]
+ CLCD::spiTransfer((Reg_Address >> 8 ) & 0xFF); // Address [15:8]
+ CLCD::spiTransfer((Reg_Address >> 0) & 0xFF); // Address [7:0]
+ CLCD::spiTransfer(0x00); // Dummy Byte
+}
+
+void CLCD::Mem_Read_Bulk (uint32_t Reg_Address, uint8_t *Data, uint16_t Len) { // Write 4-Byte Address, Read Multiple Bytes
+ CLCD::spiSelect();
+ CLCD::Mem_ReadAddr(Reg_Address);
+
+ while(Len--) {
+ *Data = CLCD::spiTransfer(0x00); // Read 1 Byte
+ *Data++;
+ }
+
+ CLCD::spiDeselect();
+}
+
+uint8_t CLCD::Mem_Read8 (uint32_t Reg_Address) { // Write 4-Byte Address, Read 1-Byte Data
+ CLCD::spiSelect();
+
+ CLCD::Mem_ReadAddr(Reg_Address);
+
+ uint8_t R_Data = CLCD::spiTransfer(0x00); // Read 1 Byte
+
+ CLCD::spiDeselect();
+
+ return(R_Data);
+}
+
+
+uint16_t CLCD::Mem_Read16 (uint32_t Reg_Address) { // Write 4-Byte Address, Read 2-Bytes Data
+ CLCD::spiSelect();
+
+ CLCD::Mem_ReadAddr(Reg_Address);
+
+ uint16_t R_Data = (((uint16_t) CLCD::spiTransfer(0x00)) << 0) | // Read Byte 1
+ (((uint16_t) CLCD::spiTransfer(0x00)) << 8); // Read Byte 2
+
+ CLCD::spiDeselect();
+
+ return(R_Data);
+}
+
+uint32_t CLCD::Mem_Read32 (uint32_t Reg_Address) { // Write 4-Byte Address, Read 4-Bytes Data
+ CLCD::spiSelect();
+
+ CLCD::Mem_ReadAddr(Reg_Address);
+
+ uint32_t R_Data = (((uint32_t) CLCD::spiTransfer(0x00)) << 0) | // Read Byte 1
+ (((uint32_t) CLCD::spiTransfer(0x00)) << 8) | // Read Byte 2
+ (((uint32_t) CLCD::spiTransfer(0x00)) << 16) | // Read Byte 3
+ (((uint32_t) CLCD::spiTransfer(0x00)) << 24); // Read Byte 4
+
+ CLCD::spiDeselect();
+
+ return(R_Data);
+}
+
+
+// MEMORY WRITE FUNCTIONS
+
+void CLCD::Mem_WriteAddr (uint32_t Reg_Address) { // Write 3-Byte Address
+ CLCD::spiTransfer((Reg_Address >> 16) | 0x80); // Address [21:16]
+ CLCD::spiTransfer((Reg_Address >> 8 ) & 0xFF); // Address [15:8]
+ CLCD::spiTransfer((Reg_Address >> 0) & 0xFF); // Address [7:0]
+}
+
+void CLCD::Mem_Write_Bulk (uint32_t Reg_Address, const void *Data, uint16_t Len, uint8_t Padding) { // Write 3-Byte Address, Multiple Bytes, plus padding bytes
+ const uint8_t* p = (const uint8_t *)Data;
+ CLCD::spiSelect();
+ CLCD::Mem_WriteAddr(Reg_Address);
+
+ while(Len--) {
+ CLCD::spiTransfer(*p++); // Write 1 Byte
+ }
+
+ while(Padding--) {
+ CLCD::spiTransfer(0); // Padding Bytes
+ }
+
+ CLCD::spiDeselect();
+}
+
+void CLCD::Mem_Write_Bulk (uint32_t Reg_Address, progmem_str Str, uint16_t Len, uint8_t Padding) { // Write 3-Byte Address, Multiple Bytes, plus padding bytes
+ const uint8_t* p = (const uint8_t *)Str;
+ CLCD::spiSelect();
+ CLCD::Mem_WriteAddr(Reg_Address);
+
+ while(Len--) {
+ CLCD::spiTransfer(pgm_read_byte_near(p++)); // Write 1 Byte
+ }
+
+ while(Padding--) {
+ CLCD::spiTransfer(0); // Padding Bytes
+ }
+
+ CLCD::spiDeselect();
+}
+
+void CLCD::Mem_Write8 (uint32_t Reg_Address, uint8_t W_Data) { // Write 3-Byte Address, Write 1-Byte Data
+ CLCD::spiSelect();
+
+ CLCD::Mem_WriteAddr(Reg_Address);
+
+ CLCD::spiTransfer(W_Data); // Write 1 Byte
+
+ CLCD::spiDeselect();
+}
+
+
+void CLCD::Mem_Write16 (uint32_t Reg_Address, uint16_t W_Data) { // Write 3-Byte Address, Write 2-Bytes Data
+ CLCD::spiSelect();
+
+ CLCD::Mem_WriteAddr(Reg_Address);
+
+ CLCD::spiTransfer((uint8_t) ((W_Data >> 0) & 0x00FF)); // Write Byte 0
+ CLCD::spiTransfer((uint8_t) ((W_Data >> 8) & 0x00FF)); // Write Byte 1
+
+ CLCD::spiDeselect();
+}
+
+
+void CLCD::Mem_Write32 (uint32_t Reg_Address, uint32_t W_Data) { // Write 3-Byte Address, Write 4-Bytes Data
+ CLCD::spiSelect();
+
+ CLCD::Mem_WriteAddr(Reg_Address);
+
+ CLCD::spiTransfer(W_Data >> 0); // Write Byte 0
+ CLCD::spiTransfer(W_Data >> 8); // Write Byte 1
+ CLCD::spiTransfer(W_Data >> 16); // Write Byte 2
+ CLCD::spiTransfer(W_Data >> 24); // Write Byte 3
+
+ CLCD::spiDeselect();
+}
+
+/**************************** FT800/810 Co-Processor Command FIFO ****************************/
+
+uint32_t CLCD::CommandFifo::getRegCmdWrite() {
+ return Mem_Read32(REG_CMD_WRITE) & 0x0FFF;
+}
+
+uint32_t CLCD::CommandFifo::getRegCmdRead() {
+ return Mem_Read32(REG_CMD_READ) & 0x0FFF;
+}
+
+bool CLCD::CommandFifo::Is_Idle() {
+ return getRegCmdRead() == getRegCmdWrite();
+}
+
+void CLCD::CommandFifo::Wait_Until_Idle() {
+ do {
+ } while(!Is_Idle());
+}
+
+#if defined(IS_FT800)
+void CLCD::CommandFifo::Start() {
+ command_write_ptr = getRegCmdWrite();
+}
+
+void CLCD::CommandFifo::Execute() {
+ Mem_Write32(REG_CMD_WRITE, command_write_ptr);
+}
+
+void CLCD::CommandFifo::Reset() {
+ Mem_Write32(REG_CMD_WRITE, 0x00000000);
+ Mem_Write32(REG_CMD_READ, 0x00000000);
+ command_write_ptr = 0;
+};
+
+template void CLCD::CommandFifo::_write_unaligned(T data, uint16_t len) {
+ const char *ptr = (const char*)data;
+ uint32_t bytes_tail, bytes_head;
+ uint32_t command_read_ptr;
+
+ /* Wait until there is enough space in the circular buffer for the transfer */
+ do {
+ command_read_ptr = getRegCmdRead();
+ if (command_read_ptr <= command_write_ptr) {
+ bytes_tail = 4096U - command_write_ptr;
+ bytes_head = command_read_ptr;
+ } else {
+ bytes_tail = command_read_ptr - command_write_ptr;
+ bytes_head = 0;
+ }
+ } while((bytes_tail + bytes_head) < len);
+
+ /* Write as many bytes as possible following REG_CMD_WRITE */
+ uint16_t bytes_to_write = min(len, bytes_tail);
+ Mem_Write_Bulk (RAM_CMD + command_write_ptr, T(ptr), bytes_to_write);
+ command_write_ptr += bytes_to_write;
+ ptr += bytes_to_write;
+ len -= bytes_to_write;
+
+ if(len > 0) {
+ /* Write remaining bytes at start of circular buffer */
+ Mem_Write_Bulk (RAM_CMD, T(ptr), len);
+ command_write_ptr = len;
+ }
+
+ if(command_write_ptr == 4096U) {
+ command_write_ptr = 0;
+ }
+}
+
+// Writes len bytes into the FIFO, if len is not
+// divisible by four, zero bytes will be written
+// to align to the boundary.
+
+template void CLCD::CommandFifo::write(T data, uint16_t len) {
+ const uint8_t padding = MULTIPLE_OF_4(len) - len;
+
+ uint8_t pad_bytes[] = {0, 0, 0, 0};
+ _write_unaligned(data, len);
+ _write_unaligned(pad_bytes, padding);
+}
+#else
+uint32_t CLCD::CommandFifo::getRegCmdBSpace() {
+ return Mem_Read32(REG_CMDB_SPACE) & 0x0FFF;
+}
+
+void CLCD::CommandFifo::Cmd_Start() {
+}
+
+void CLCD::CommandFifo::Cmd_Execute() {
+}
+
+void CLCD::CommandFifo::Reset() {
+ Mem_Write32(REG_CMD_WRITE, 0x00000000);
+ Mem_Write32(REG_CMD_READ, 0x00000000);
+};
+
+// Writes len bytes into the FIFO, if len is not
+// divisible by four, zero bytes will be written
+// to align to the boundary.
+
+template void CLCD::CommandFifo::write(T data, uint16_t len) {
+ const uint8_t padding = MULTIPLE_OF_4(len) - len;
+
+ // The FT810 provides a special register that can be used
+ // for writing data without us having to do our own FIFO
+ // management.
+ uint32_t Command_Space = getRegCmdBSpace();
+ while(Command_Space < len + padding) {
+ Command_Space = getRegCmdBSpace();
+ }
+ Mem_Write_Bulk(REG_CMDB_WRITE, data, len, padding);
+}
+#endif
+
+// CO_PROCESSOR COMMANDS
+
+void CLCD::CommandFifo::Cmd (uint32_t cmd32) { // Writes a 32-bit (4 Bytes) Value to the Co-processor Command Buffer FIFO
+ write(&cmd32, sizeof(uint32_t));
+}
+
+void CLCD::CommandFifo::Cmd (void* data, uint16_t len) { // Writes a data structure - always a multiple of 32 bits - to the Co_Processor FIFO. // Data structure includes the 32-bit Co_Processor command.
+ write(data, len);
+}
+
+
+void CLCD::CommandFifo::Cmd_Str (char* data) {
+ write(data, strlen(data)+1);
+}
+
+void CLCD::CommandFifo::Cmd_Str (progmem_str data) {
+ write(data, strlen_P((const char*)data)+1);
+}
+
+#endif // _AO_FT810_SPI_H
+
+
+
+
+
diff --git a/Marlin/AO_FT810_UI_Bitmaps.h b/Marlin/AO_FT810_UI_Bitmaps.h
new file mode 100644
index 000000000..11aab1532
--- /dev/null
+++ b/Marlin/AO_FT810_UI_Bitmaps.h
@@ -0,0 +1,177 @@
+/***************************
+ * AO_FT810_Menu_Bitmaps.h *
+ ***************************/
+
+/****************************************************************************
+ * Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * To view a copy of the GNU General Public License, go to the following *
+ * location: . *
+ ****************************************************************************/
+
+
+// Colors RGB332
+
+#define COLOR0 0x00 // Black
+#define COLOR1 0x49 // Gray
+#define COLOR2 0x7C // Yellow Green
+#define COLOR3 0xFF // White
+
+// L1 Font Data for Widgets
+
+const PROGMEM CLCD::bitmap_info_t Extruder_Icon_Info = {
+ .format = L1,
+ .linestride = 3,
+ .filter = BILINEAR,
+ .wrapx = BORDER,
+ .wrapy = BORDER,
+ .RAMG_addr = RAM_G + 8000,
+ .width = 24,
+ .height = 23,
+};
+
+const PROGMEM unsigned char Extruder_Icon[] = {0x3F, 0xFF, 0xFC,
+ 0x7F, 0xFF, 0xFE,
+ 0xC0, 0x00, 0x03,
+ 0xC0, 0x00, 0x03,
+ 0xC0, 0x00, 0x03,
+ 0xC0, 0x00, 0x03,
+ 0x7F, 0xFF, 0xFE,
+ 0x3F, 0xFF, 0xFC,
+ 0x3F, 0xFF, 0xFC,
+ 0x7F, 0xFF, 0xFE,
+ 0xC0, 0x00, 0x03,
+ 0xC0, 0x00, 0x03,
+ 0xC0, 0x00, 0x03,
+ 0xC0, 0x00, 0x03,
+ 0x7F, 0xFF, 0xFE,
+ 0x7F, 0xFF, 0xFE,
+ 0x07, 0xFF, 0xE0,
+ 0x03, 0xFF, 0xC0,
+ 0x01, 0x81, 0x80,
+ 0x00, 0xC3, 0x00,
+ 0x00, 0x66, 0x00,
+ 0x00, 0x3C, 0x00,
+ 0x00, 0x3C, 0x00};
+
+const PROGMEM CLCD::bitmap_info_t Bed_Heat_Icon_Info = {
+ .format = L1,
+ .linestride = 4,
+ .filter = BILINEAR,
+ .wrapx = BORDER,
+ .wrapy = BORDER,
+ .RAMG_addr = RAM_G + 8100,
+ .width = 32,
+ .height = 23,
+};
+
+const PROGMEM unsigned char Bed_Heat_Icon[] = {0x01, 0x81, 0x81, 0x80,
+ 0x01, 0x81, 0x81, 0x80,
+ 0x00, 0xC0, 0xC0, 0xC0,
+ 0x00, 0xC0, 0xC0, 0xC0,
+ 0x00, 0x60, 0x60, 0x60,
+ 0x00, 0x60, 0x60, 0x60,
+ 0x00, 0xC0, 0xC0, 0xC0,
+ 0x00, 0xC0, 0xC0, 0xC0,
+ 0x01, 0x81, 0x81, 0x80,
+ 0x01, 0x81, 0x81, 0x80,
+ 0x03, 0x03, 0x03, 0x00,
+ 0x03, 0x03, 0x03, 0x00,
+ 0x06, 0x06, 0x06, 0x00,
+ 0x06, 0x06, 0x06, 0x00,
+ 0x03, 0x03, 0x03, 0x00,
+ 0x03, 0x03, 0x03, 0x00,
+ 0x01, 0x81, 0x81, 0x80,
+ 0x01, 0x81, 0x81, 0x80,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC0, 0x00, 0x00, 0x03,
+ 0xFF, 0xFF, 0xFF, 0xFF};
+
+const PROGMEM CLCD::bitmap_info_t Fan_Icon_Info = {
+ .format = L1,
+ .linestride = 4,
+ .filter = BILINEAR,
+ .wrapx = BORDER,
+ .wrapy = BORDER,
+ .RAMG_addr = RAM_G + 8300,
+ .width = 32,
+ .height = 32,
+};
+
+const PROGMEM unsigned char Fan_Icon[] = {0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xF8, 0x00, 0x00, 0x1F,
+ 0xF0, 0x03, 0xF8, 0x0F,
+ 0xE0, 0x07, 0xF0, 0x07,
+ 0xC0, 0x0F, 0xE0, 0x03,
+ 0xC0, 0x1F, 0xE0, 0x03,
+ 0xC0, 0x1F, 0xE0, 0x03,
+ 0xC0, 0x0F, 0xE0, 0x03,
+ 0xC0, 0x07, 0xE0, 0x03,
+ 0xC0, 0x03, 0xC0, 0x03,
+ 0xD0, 0x00, 0x00, 0xC3,
+ 0xD8, 0x03, 0xC1, 0xE3,
+ 0xDF, 0xC7, 0xE3, 0xF3,
+ 0xDF, 0xEF, 0xF7, 0xFB,
+ 0xDF, 0xEF, 0xF7, 0xFB,
+ 0xDF, 0xEF, 0xF7, 0xFB,
+ 0xDF, 0xEF, 0xF7, 0xFB,
+ 0xCF, 0xC7, 0xE3, 0xFB,
+ 0xC7, 0x83, 0xC0, 0x1B,
+ 0xC3, 0x00, 0x00, 0x0B,
+ 0xC0, 0x03, 0xC0, 0x03,
+ 0xC0, 0x07, 0xE0, 0x03,
+ 0xC0, 0x07, 0xF0, 0x03,
+ 0xC0, 0x07, 0xF8, 0x03,
+ 0xC0, 0x07, 0xF8, 0x03,
+ 0xC0, 0x07, 0xF0, 0x03,
+ 0xE0, 0x0F, 0xE0, 0x07,
+ 0xF0, 0x1F, 0xC0, 0x0F,
+ 0xF8, 0x00, 0x00, 0x1F,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF};
+
+
+const PROGMEM CLCD::bitmap_info_t TD_Icon_Info = {
+ .format = L1,
+ .linestride = 7,
+ .filter = BILINEAR,
+ .wrapx = BORDER,
+ .wrapy = BORDER,
+ .RAMG_addr = RAM_G + 8400,
+ .width = 50,
+ .height = 20,
+};
+
+const PROGMEM unsigned char TD_Icon[] = {0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, // Thumb Drive Widget
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x80,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x80,
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00};
diff --git a/Marlin/AO_FT810_UI_Screens.h b/Marlin/AO_FT810_UI_Screens.h
new file mode 100644
index 000000000..291b961d5
--- /dev/null
+++ b/Marlin/AO_FT810_UI_Screens.h
@@ -0,0 +1,1197 @@
+/****************************************************************************
+ * Written By Mark Pelletier 2018 - Aleph Objects, Inc. *
+ * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * To view a copy of the GNU General Public License, go to the following *
+ * location: . *
+ ****************************************************************************/
+
+#define STATUS_MESSAGE_BUFFER_LENGTH 32
+char lcd_status_message[STATUS_MESSAGE_BUFFER_LENGTH] = WELCOME_MSG;
+
+static float marlin_x_axis = 100;
+static float marlin_y_axis = 50;
+static float marlin_z_axis = 170;
+static int marlin_e0_temp = 25;
+static int marlin_e1_temp = 25;
+static int marlin_bed_temp = 25;
+static int marlin_fan_speed = 25;
+static float marlin_x_steps = 100;
+static float marlin_y_steps = 100;
+static float marlin_z_steps = 100;
+static float marlin_e0_steps = 100;
+static float marlin_z_offset = 0.150;
+
+/**************************** GRID LAYOUT MACROS **************************/
+
+/* The grid layout macros allow buttons to be arranged on a grid so
+ * that their locations become independent of the display size. The
+ * layout model is similar to that of HTML TABLEs.
+ *
+ * These macros are meant to be evaluated into constants at compile
+ * time, so resolution independence can be as efficient as using
+ * hard-coded coordinates.
+ */
+
+// Margin defines the margin (in pixels) on each side of a button in
+// the layout
+
+#define MARGIN_L 5
+#define MARGIN_R 5
+#define MARGIN_T 5
+#define MARGIN_B 5
+
+// EDGE_R adds some black space on the right edge of the display
+// This shifts some of the screens left to visually center them.
+
+#define EDGE_R 0
+
+// GRID_X and GRID_Y computes the positions of the divisions on
+// the layout grid.
+#if defined(LCD_PORTRAIT)
+#define GRID_X(x) ((x)*(Vsize-EDGE_R)/GRID_COLS)
+#define GRID_Y(y) ((y)*Hsize/GRID_ROWS)
+#else
+#define GRID_X(x) ((x)*(Hsize-EDGE_R)/GRID_COLS)
+#define GRID_Y(y) ((y)*Vsize/GRID_ROWS)
+#endif
+
+// BTN_X, BTN_Y, BTN_W and BTN_X returns the top-left and width
+// and height of a button, taking into account the button margins.
+
+#define BTN_X(x) (GRID_X(x-1) + MARGIN_L)
+#define BTN_Y(y) (GRID_Y(y-1) + MARGIN_T)
+#define BTN_W(w) (GRID_X(w) - MARGIN_L - MARGIN_R)
+#define BTN_H(h) (GRID_Y(h) - MARGIN_T - MARGIN_B)
+
+// Abbreviations for common phrases, to allow a button to be
+// defined in one line of source.
+#define BTN_POS(x,y) BTN_X(x), BTN_Y(y)
+#define BTN_SIZE(w,h) BTN_W(w), BTN_H(h)
+#define BTN cmd.Cmd_Draw_Button
+#define BTX cmd.Cmd_Draw_Button_Text
+#define BTI cmd.Cmd_Draw_Button_Icon
+#define BTN_TAG(t) cmd.Cmd_Set_Tag(t);
+#define RGB(rgb) cmd.Cmd_Set_Foreground_Color(Theme::rgb);
+#define TOGGLE(val) cmd.Cmd_Set_Foreground_Color(val ? Theme::toggle_on : Theme::toggle_off);
+
+#define FONT_SML Theme::font_small
+#define FONT_MED Theme::font_medium
+#define FONT_LRG Theme::font_large
+
+#define MENU_BTN_STYLE Theme::font_medium, OPT_3D
+
+/************************* MENU SCREEN DECLARATIONS *************************/
+
+class BootScreen : public UIScreen {
+ public:
+ static void onRefresh();
+ static void onIdle();
+};
+
+class AboutScreen : public UIScreen {
+ private:
+ static void playChime();
+ static void draw(bool);
+ public:
+ static void onEntry();
+ static void onRefresh();
+ static void onTouchStart(uint8_t tag);
+};
+
+class StatusScreen : public UIScreen {
+ public:
+ static void onRefresh();
+ static void onStartup();
+ static void onEntry();
+ static void onIdle();
+ static void onTouchStart(uint8_t tag);
+};
+
+class MenuScreen : public UIScreen {
+ public:
+ static void onRefresh();
+ static void onTouchStart(uint8_t tag);
+};
+
+class CalibrationScreen : public UIScreen {
+ public:
+ static void onRefresh();
+ static void onIdle();
+};
+
+class CalibrationRegistersScreen : public UIScreen {
+ public:
+ static void onRefresh();
+ static void onTouchStart(uint8_t tag);
+};
+
+class AdvancedSettingsScreen : public UIScreen {
+ public:
+ static void onRefresh();
+ static void onTouchStart(uint8_t tag);
+};
+
+class ValueAdjusters : public UIScreen {
+ protected:
+ static float increment;
+ static void static_heading(progmem_str heading);
+ static void static_value(int line, progmem_str value);
+ static void dynamic_value(int line, float value, progmem_str units);
+ public:
+ static void onTouchStart(uint8_t tag);
+};
+
+class MoveAxisScreen : public ValueAdjusters {
+ public:
+ static void onRefresh();
+ static void onTouchHeld(uint8_t tag);
+};
+
+class StepsScreen : public ValueAdjusters {
+ public:
+ static void onRefresh();
+ static void onTouchHeld(uint8_t tag);
+};
+
+class ZOffsetScreen : public ValueAdjusters {
+ public:
+ static void onRefresh();
+ static void onTouchHeld(uint8_t tag);
+};
+
+class TemperatureScreen : public ValueAdjusters {
+ public:
+ static void onRefresh();
+ static void onTouchHeld(uint8_t tag);
+};
+
+/******************************* MENU SCREEN TABLE ******************************/
+
+SCREEN_TABLE {
+ DECL_SCREEN(BootScreen),
+ DECL_SCREEN(AboutScreen),
+ DECL_SCREEN(CalibrationScreen),
+ DECL_SCREEN(StatusScreen),
+ DECL_SCREEN(MenuScreen),
+ DECL_SCREEN(MoveAxisScreen),
+ DECL_SCREEN(AdvancedSettingsScreen),
+ DECL_SCREEN(StepsScreen),
+ DECL_SCREEN(ZOffsetScreen),
+ DECL_SCREEN(TemperatureScreen),
+ DECL_SCREEN(CalibrationRegistersScreen)
+};
+
+SCREEN_TABLE_POST
+
+/************************************ MENU THEME ********************************/
+
+namespace Theme {
+ const uint32_t olive_darkest = 0x2A2F0A;
+ const uint32_t olive_dark = 0x495212;
+ const uint32_t olive_light = 0x8C9D22;
+
+ const uint32_t background = 0x707070;
+ const uint32_t x_axis = 0x500000;
+ const uint32_t y_axis = 0x005000;
+ const uint32_t z_axis = 0x000050;
+ const uint32_t e_axis = 0x000000;
+ const uint32_t menu_btn = olive_dark;
+ const uint32_t navi_btn = olive_light;
+
+ const uint32_t toggle_on = olive_light;
+ const uint32_t toggle_off = olive_darkest;
+ const uint32_t disabled = background;
+
+ // About screen
+ const uint32_t about_bg = olive_dark;
+ const uint32_t about_btn = olive_darkest;
+
+ // Adjustment Screens
+
+ const uint32_t adjust_bg = olive_dark;
+ const uint32_t incr_btn = olive_darkest;
+
+ // Status screen
+ const uint32_t stop_btn = 0xF02020;
+ const uint32_t prnt_btn = 0x20D020;
+ const uint32_t progress = 0x404040;
+ const uint32_t status_msg = 0x404040;
+ const uint32_t fan_speed = 0x6060D0;
+ const uint32_t temp = 0xD04000;
+ const uint32_t axis_label = 0x404040;
+
+ // Calibration Registers Screen
+ const uint32_t transformA = 0x3010D0;
+ const uint32_t transformB = 0x4010D0;
+ const uint32_t transformC = 0x5010D0;
+ const uint32_t transformD = 0x6010D0;
+ const uint32_t transformE = 0x7010D0;
+ const uint32_t transformF = 0x8010D0;
+ const uint32_t transformVal = 0x104010;
+
+#if defined(LCD_800x480)
+ #if defined(LCD_PORTRAIT)
+ const int16_t font_small = 29;
+ const int16_t font_medium = 30;
+ const int16_t font_large = 30;
+ #else
+ const int16_t font_small = 30;
+ const int16_t font_medium = 30;
+ const int16_t font_large = 31;
+ #endif
+ const float icon_scale = 1.0;
+#else
+ #if defined(LCD_PORTRAIT)
+ const int16_t font_small = 27;
+ const int16_t font_medium = 28;
+ const int16_t font_large = 28;
+ #else
+ const int16_t font_small = 28;
+ const int16_t font_medium = 29;
+ const int16_t font_large = 30;
+ #endif
+ const float icon_scale = 0.7;
+#endif
+};
+
+/******************************** BOOT SCREEN ****************************/
+
+void BootScreen::onRefresh() {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+ cmd.Cmd_Clear_Color(Theme::background);
+ cmd.Cmd_Clear(1,1,1);
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+
+ cmd.Wait_Until_Idle();
+
+ CLCD::Turn_On_Backlight();
+}
+
+void BootScreen::onIdle() {
+ GOTO_SCREEN(CalibrationScreen);
+}
+
+/******************************** ABOUT SCREEN ****************************/
+
+
+void AboutScreen::onEntry() {
+ draw(false);
+ playChime();
+ draw(true);
+}
+
+void AboutScreen::onRefresh() {
+ draw(true);
+}
+
+void AboutScreen::draw(bool showOkay) {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+ cmd.Cmd_Clear_Color(Theme::about_bg);
+ cmd.Cmd_Clear(1,1,1);
+
+ #define GRID_COLS 4
+ #define GRID_ROWS 6
+
+ BTX( BTN_POS(1,2), BTN_SIZE(4,1), F("Color LCD Interface"), FONT_LRG);
+ BTN_TAG(2) BTX( BTN_POS(1,3), BTN_SIZE(4,1), F("(c) 2018 Aleph Objects, Inc."), FONT_LRG);
+
+ if(showOkay) {
+ BTN_TAG(1) RGB(about_btn) BTN( BTN_POS(2,5), BTN_SIZE(2,1), F("Okay"), MENU_BTN_STYLE);
+ }
+
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void AboutScreen::onTouchStart(uint8_t tag) {
+ switch(tag) {
+ case 1: GOTO_PREVIOUS(); return;
+ case 2: GOTO_SCREEN(CalibrationRegistersScreen); return;
+ }
+}
+
+void AboutScreen::playChime() {
+ CLCD::Mem_Write8(REG_VOL_SOUND, 0xFF);
+ CLCD::Mem_Write16(REG_SOUND, (0x37<< 8) | 0x47); // C8 MIDI note on xylophone 37
+ CLCD::Mem_Write8(REG_PLAY, 1);
+
+ delay(800);
+
+ CLCD::Mem_Write16(REG_SOUND, (0x40<< 8) | 0x47); // C8 MIDI note on xylophone 40
+ CLCD::Mem_Write8(REG_PLAY, 1);
+
+ delay(800);
+
+ CLCD::Mem_Write16(REG_SOUND, (0x3C<< 8) | 0x47); // C8 MIDI note on xylophone 3C
+ CLCD::Mem_Write8(REG_PLAY, 1);
+
+ delay(1200);
+
+ CLCD::Mem_Write16(REG_SOUND, 0);
+ CLCD::Mem_Write8(REG_PLAY, 1);
+}
+
+/*********************************** STATUS SCREEN ******************************/
+
+void StatusScreen::onStartup() {
+ // Load USB Thumb Drive Bitmap
+ CLCD::Flash_Write_RGB332_Bitmap(TD_Icon_Info.RAMG_addr, TD_Icon, sizeof(TD_Icon));
+
+ // Load Extruder Bitmap
+ CLCD::Flash_Write_RGB332_Bitmap(Extruder_Icon_Info.RAMG_addr, Extruder_Icon, sizeof(Extruder_Icon));
+
+ // Load Bed Heat Bitmap
+ CLCD::Flash_Write_RGB332_Bitmap(Bed_Heat_Icon_Info.RAMG_addr, Bed_Heat_Icon, sizeof(Bed_Heat_Icon));
+
+ // Load Fan Percent Bitmap
+ CLCD::Flash_Write_RGB332_Bitmap(Fan_Icon_Info.RAMG_addr, Fan_Icon, sizeof(Fan_Icon));
+}
+
+void StatusScreen::onRefresh() {
+ static CLCD::DLCache dlcache;
+
+ if(dlcache.hasData()) {
+ dlcache.append();
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+ cmd.Cmd_Clear_Color(Theme::background);
+ cmd.Cmd_Clear(1,1,1);
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_ROWS 9
+ #else
+ #define GRID_ROWS 8
+ #endif
+
+ BTN_TAG(0)
+ #if defined(LCD_PORTRAIT)
+ #define GRID_COLS 8
+ RGB(temp) BTN( BTN_POS(1,1), BTN_SIZE(4,2), F(""), FONT_SML, OPT_FLAT);
+ RGB(temp) BTN( BTN_POS(1,1), BTN_SIZE(8,1), F(""), FONT_SML, OPT_FLAT);
+ RGB(fan_speed) BTN( BTN_POS(5,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
+ RGB(progress) BTN( BTN_POS(1,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
+ RGB(progress) BTN( BTN_POS(5,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
+ #else
+ #define GRID_COLS 12
+ RGB(temp) BTN( BTN_POS(1,1), BTN_SIZE(4,2), F(""), FONT_SML, OPT_FLAT);
+ RGB(temp) BTN( BTN_POS(1,1), BTN_SIZE(8,1), F(""), FONT_SML, OPT_FLAT);
+ RGB(fan_speed) BTN( BTN_POS(5,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
+ RGB(progress) BTN( BTN_POS(9,1), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
+ RGB(progress) BTN( BTN_POS(9,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
+ #endif
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_COLS 3
+ RGB(axis_label) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
+ RGB(axis_label) BTN( BTN_POS(1,6), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
+ RGB(axis_label) BTN( BTN_POS(1,7), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
+ BTX( BTN_POS(1,5), BTN_SIZE(1,1), F("X"), FONT_SML);
+ BTX( BTN_POS(1,6), BTN_SIZE(1,1), F("Y"), FONT_SML);
+ BTX( BTN_POS(1,7), BTN_SIZE(1,1), F("Z"), FONT_SML);
+ RGB(x_axis) BTN( BTN_POS(2,5), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
+ RGB(y_axis) BTN( BTN_POS(2,6), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
+ RGB(z_axis) BTN( BTN_POS(2,7), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
+ #else
+ #define GRID_COLS 3
+ #define MARGIN_T 10
+ RGB(axis_label) BTN( BTN_POS(1,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
+ RGB(axis_label) BTN( BTN_POS(2,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
+ RGB(axis_label) BTN( BTN_POS(3,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
+ BTX( BTN_POS(1,5), BTN_SIZE(1,1), F("X"), FONT_SML);
+ BTX( BTN_POS(2,5), BTN_SIZE(1,1), F("Y"), FONT_SML);
+ BTX( BTN_POS(3,5), BTN_SIZE(1,1), F("Z"), FONT_SML);
+ #define MARGIN_T 0
+ RGB(x_axis) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
+ RGB(y_axis) BTN( BTN_POS(2,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
+ RGB(z_axis) BTN( BTN_POS(3,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
+ #define MARGIN_T 5
+ #endif
+
+ #define GRID_COLS 4
+ #if defined(LCD_PORTRAIT)
+ BTN_TAG(1) RGB(stop_btn) BTN( BTN_POS(1,8), BTN_SIZE(4,1), F("STOP"), MENU_BTN_STYLE);
+ BTN_TAG(3) RGB(navi_btn) BTN( BTN_POS(1,9), BTN_SIZE(2,1), F(""), MENU_BTN_STYLE);
+ BTN_TAG(4) RGB(navi_btn) BTN( BTN_POS(3,9), BTN_SIZE(2,1), F("MENU"), MENU_BTN_STYLE);
+ #else
+ BTN_TAG(1) RGB(stop_btn) BTN( BTN_POS(1,7), BTN_SIZE(2,2), F("STOP"), MENU_BTN_STYLE);
+ BTN_TAG(3) RGB(navi_btn) BTN( BTN_POS(3,7), BTN_SIZE(1,2), F(""), MENU_BTN_STYLE);
+ BTN_TAG(4) RGB(navi_btn) BTN( BTN_POS(4,7), BTN_SIZE(1,2), F("MENU"), MENU_BTN_STYLE);
+ #endif
+
+ // Draw Thumb Drive Bitmap on USB Button
+
+ cmd.Cmd_Bitmap_Source(TD_Icon_Info);
+ cmd.Cmd_Bitmap_Layout(TD_Icon_Info);
+ cmd.Cmd_Bitmap_Size (TD_Icon_Info);
+
+ BTN_TAG(3)
+ #if defined(LCD_PORTRAIT)
+ BTI(BTN_POS(1,9), BTN_SIZE(2,1), TD_Icon_Info, Theme::icon_scale);
+ #else
+ BTI(BTN_POS(3,7), BTN_SIZE(1,2), TD_Icon_Info, Theme::icon_scale);
+ #endif
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_COLS 8
+ #else
+ #define GRID_COLS 12
+ #endif
+
+ // Draw Extruder Bitmap on Extruder Temperature Button
+
+ cmd.Cmd_Bitmap_Source(Extruder_Icon_Info);
+ cmd.Cmd_Bitmap_Layout(Extruder_Icon_Info);
+ cmd.Cmd_Bitmap_Size (Extruder_Icon_Info);
+
+ BTN_TAG(0)
+ BTI(BTN_POS(1,1), BTN_SIZE(1,1), Extruder_Icon_Info, Theme::icon_scale);
+ BTI(BTN_POS(5,1), BTN_SIZE(1,1), Extruder_Icon_Info, Theme::icon_scale);
+
+ #if EXTRUDERS == 1
+ BTX( BTN_POS(6,1), BTN_SIZE(2,1), F("-"), FONT_MED);
+ #endif
+
+ // Draw Bed Heat Bitmap on Bed Heat Button
+ cmd.Cmd_Bitmap_Source(Bed_Heat_Icon_Info);
+ cmd.Cmd_Bitmap_Layout(Bed_Heat_Icon_Info);
+ cmd.Cmd_Bitmap_Size (Bed_Heat_Icon_Info);
+
+ BTN_TAG(0)
+ BTI(BTN_POS(1,2), BTN_SIZE(1,1), Bed_Heat_Icon_Info, Theme::icon_scale);
+
+ // Draw Fan Percent Bitmap on Bed Heat Button
+
+ cmd.Cmd_Bitmap_Source(Fan_Icon_Info);
+ cmd.Cmd_Bitmap_Layout(Fan_Icon_Info);
+ cmd.Cmd_Bitmap_Size (Fan_Icon_Info);
+
+ BTN_TAG(0)
+ BTI(BTN_POS(5,2), BTN_SIZE(1,1), Fan_Icon_Info, Theme::icon_scale);
+
+ cmd.Cmd_Execute();
+ dlcache.store();
+ }
+
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ /* Dynamic content, non-cached data follows */
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_ROWS 9
+ #else
+ #define GRID_ROWS 8
+ #endif
+
+ BTN_TAG(0)
+
+ const uint32_t elapsed = Marlin_LCD_API::getProgress_seconds_elapsed();
+ const uint8_t hrs = elapsed/3600;
+ const uint8_t min = (elapsed/60)%60;
+ char b[255];
+ #if defined(LCD_PORTRAIT)
+ #define GRID_COLS 8
+ sprintf_P(b, PSTR(" %02d : %02d"), hrs, min);
+ BTX( BTN_POS(1,3), BTN_SIZE(4,1), b, FONT_MED);
+
+ sprintf_P(b, PSTR("%-3d %%"), Marlin_LCD_API::getProgress_percent() );
+ BTX( BTN_POS(5,3), BTN_SIZE(4,1), b, FONT_MED);
+ #else
+ #define GRID_COLS 12
+ sprintf_P(b, PSTR(" %02d : %02d"), hrs, min);
+ BTX( BTN_POS(9,1), BTN_SIZE(4,1), b, FONT_MED);
+
+ sprintf_P(b, PSTR("%-3d %%"), Marlin_LCD_API::getProgress_percent() );
+ BTX( BTN_POS(9,2), BTN_SIZE(4,1), b, FONT_MED);
+ #endif
+
+ sprintf_P(b, PSTR("%-3d / %-3d C"), Marlin_LCD_API::getActualTemp_celsius(1), Marlin_LCD_API::getActualTemp_celsius(1) );
+ BTX( BTN_POS(2,1), BTN_SIZE(3,1), b, FONT_MED);
+
+ #if EXTRUDERS == 2
+ sprintf_P(b, PSTR("%-3d / %-3d C"), Marlin_LCD_API::getActualTemp_celsius(2), Marlin_LCD_API::getTargetTemp_celsius(2) );
+ BTX( BTN_POS(6,1), BTN_SIZE(3,1), b, FONT_MED);
+ #endif
+
+ sprintf_P(b, PSTR("%-3d / %-3d " ), Marlin_LCD_API::getActualTemp_celsius(0), Marlin_LCD_API::getActualTemp_celsius(0) );
+ BTX( BTN_POS(2,2), BTN_SIZE(3,1), b, FONT_MED);
+
+ sprintf_P(b, PSTR("%-3d %%"), Marlin_LCD_API::getFan_percent(0) );
+ BTX( BTN_POS(6,2), BTN_SIZE(3,1), b, FONT_MED);
+
+ #define GRID_COLS 1
+ #if defined(LCD_PORTRAIT)
+ RGB(status_msg) BTN( BTN_POS(1,4), BTN_SIZE(1,1), lcd_status_message, FONT_LRG, OPT_FLAT);
+ #else
+ RGB(status_msg) BTN( BTN_POS(1,3), BTN_SIZE(1,2), lcd_status_message, FONT_LRG, OPT_FLAT);
+ #endif
+
+ #define GRID_COLS 3
+
+ dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::X), 5, 1, b);
+ strcat_P(b, PSTR(" mm"));
+ #if defined(LCD_PORTRAIT)
+ BTX( BTN_POS(2,5), BTN_SIZE(2,1), b, FONT_MED);
+ #else
+ BTX( BTN_POS(1,6), BTN_SIZE(1,1), b, FONT_MED);
+ #endif
+
+
+ dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Y), 5, 1, b);
+ strcat_P(b, PSTR(" mm"));
+ #if defined(LCD_PORTRAIT)
+ BTX( BTN_POS(2,6), BTN_SIZE(2,1), b, FONT_MED);
+ #else
+ BTX( BTN_POS(2,6), BTN_SIZE(1,1), b, FONT_MED);
+ #endif
+
+ dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Z), 5, 1, b);
+ strcat_P(b, PSTR(" mm"));
+ #if defined(LCD_PORTRAIT)
+ BTX( BTN_POS(2,7), BTN_SIZE(2,1), b, FONT_MED);
+ #else
+ BTX( BTN_POS(3,6), BTN_SIZE(1,1), b, FONT_MED);
+ #endif
+
+ #define MARGIN_T 5
+
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void StatusScreen::onEntry() {
+ onRefresh();
+}
+
+void StatusScreen::onIdle() {
+ onRefresh();
+}
+
+void StatusScreen::onTouchStart(uint8_t tag) {
+ switch(tag) {
+ case 4: GOTO_SCREEN(MenuScreen); break;
+ }
+}
+
+/************************************ MENU SCREEN *******************************/
+
+void MenuScreen::onRefresh() {
+ static CLCD::DLCache dlcache;
+
+ if(dlcache.hasData()) {
+ dlcache.append();
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+
+ cmd.Cmd_Clear_Color(Theme::background);
+ cmd.Cmd_Clear(1,1,1);
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_ROWS 7
+ #define GRID_COLS 2
+ BTN_TAG(2) RGB(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home"), MENU_BTN_STYLE);
+ BTN_TAG(3) RGB(menu_btn) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Move Axis"), MENU_BTN_STYLE);
+
+ #define GRID_COLS 1
+ BTN_TAG(4) RGB(menu_btn) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Disable Steppers"), MENU_BTN_STYLE);
+
+ BTN_TAG(5) RGB(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Temperature"), MENU_BTN_STYLE);
+ BTN_TAG(6) RGB(menu_btn) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("Advanced Settings"), MENU_BTN_STYLE);
+ BTN_TAG(8) RGB(menu_btn) BTN( BTN_POS(1,5), BTN_SIZE(1,1), F("Recalibrate Screen"), MENU_BTN_STYLE);
+ BTN_TAG(7) RGB(menu_btn) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F("About Firmware"), MENU_BTN_STYLE);
+
+ #define MARGIN_T 15
+ BTN_TAG(1) RGB(navi_btn) BTN( BTN_POS(1,7), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
+ #define MARGIN_T 5
+ #else
+ #define GRID_ROWS 4
+ #define GRID_COLS 2
+ BTN_TAG(2) RGB(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home"), MENU_BTN_STYLE);
+ BTN_TAG(3) RGB(menu_btn) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Move Axis"), MENU_BTN_STYLE);
+ BTN_TAG(4) RGB(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Disable Steppers"), MENU_BTN_STYLE);
+
+ BTN_TAG(5) RGB(menu_btn) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Temperature"), MENU_BTN_STYLE);
+ BTN_TAG(6) RGB(menu_btn) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Configuration"), MENU_BTN_STYLE);
+ BTN_TAG(7) RGB(menu_btn) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("About Firmware"), MENU_BTN_STYLE);
+
+ #define MARGIN_T 15
+ #define GRID_COLS 1
+ BTN_TAG(1) RGB(navi_btn) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
+ #define MARGIN_T 5
+ #endif
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+ dlcache.store();
+ }
+}
+
+void MenuScreen::onTouchStart(uint8_t tag) {
+ switch(tag) {
+ case 1: GOTO_PREVIOUS(); break;
+ case 3: GOTO_SCREEN(MoveAxisScreen); break;
+ case 5: GOTO_SCREEN(TemperatureScreen); break;
+ case 6: GOTO_SCREEN(AdvancedSettingsScreen); break;
+ case 7: GOTO_SCREEN(AboutScreen); break;
+ case 8: GOTO_SCREEN(CalibrationScreen); break;
+ }
+}
+
+/******************************* CONFIGURATION SCREEN ****************************/
+
+void AdvancedSettingsScreen::onRefresh() {
+ static CLCD::DLCache dlcache;
+
+ if(dlcache.hasData()) {
+ dlcache.append();
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+
+ cmd.Cmd_Clear_Color(Theme::background);
+ cmd.Cmd_Clear(1,1,1);
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_ROWS 6
+ #else
+ #define GRID_ROWS 4
+ #endif
+
+ #define GRID_COLS 2
+
+ #define MARGIN_T 15
+ #if defined(LCD_PORTRAIT)
+ BTN_TAG(3) RGB(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,2), F("Z Offset "), MENU_BTN_STYLE);
+ BTN_TAG(4) RGB(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(1,2), F("Steps/mm"), MENU_BTN_STYLE);
+
+ BTN_TAG(6) RGB(disabled) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Velocity "), MENU_BTN_STYLE);
+ BTN_TAG(7) RGB(disabled) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Acceleration"), MENU_BTN_STYLE);
+ BTN_TAG(8) RGB(disabled) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("Jerk"), MENU_BTN_STYLE);
+ BTN_TAG(5) RGB(menu_btn) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F("Restore Failsafe"), MENU_BTN_STYLE);
+ BTN_TAG(1) RGB(navi_btn) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F("Save"), MENU_BTN_STYLE);
+ BTN_TAG(2) RGB(navi_btn) BTN( BTN_POS(2,6), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
+ #else
+ BTN_TAG(3) RGB(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Z Offset "), MENU_BTN_STYLE);
+ BTN_TAG(4) RGB(menu_btn) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Steps/mm"), MENU_BTN_STYLE);
+
+ BTN_TAG(6) RGB(disabled) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Velocity "), MENU_BTN_STYLE);
+ BTN_TAG(7) RGB(disabled) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Acceleration"), MENU_BTN_STYLE);
+ BTN_TAG(8) RGB(disabled) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("Jerk"), MENU_BTN_STYLE);
+ BTN_TAG(5) RGB(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Restore Failsafe"), MENU_BTN_STYLE);
+ #define GRID_COLS 4
+ BTN_TAG(1) RGB(navi_btn) BTN( BTN_POS(1,4), BTN_SIZE(2,1), F("Save"), MENU_BTN_STYLE);
+ BTN_TAG(2) RGB(navi_btn) BTN( BTN_POS(3,4), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
+ #endif
+
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+
+ cmd.Cmd_Execute();
+ dlcache.store();
+ }
+}
+
+void AdvancedSettingsScreen::onTouchStart(uint8_t tag) {
+ switch(tag) {
+ case 1: GOTO_PREVIOUS(); break;
+ case 2: GOTO_PREVIOUS(); break;
+ case 3: GOTO_SCREEN(ZOffsetScreen); break;
+ case 4: GOTO_SCREEN(StepsScreen); break;
+ }
+}
+
+/******************************** CALIBRATION SCREEN ****************************/
+
+void CalibrationScreen::onRefresh() {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+ cmd.Cmd_Clear_Color(Theme::background);
+ cmd.Cmd_Clear(1,1,1);
+
+ #define GRID_COLS 4
+ #define GRID_ROWS 16
+ #if defined(LCD_PORTRAIT)
+ BTX( BTN_POS(1,8), BTN_SIZE(4,1), F("Touch the dots"), FONT_LRG);
+ BTX( BTN_POS(1,9), BTN_SIZE(4,1), F("to calibrate"), FONT_LRG);
+ #else
+ BTX( BTN_POS(1,1), BTN_SIZE(4,16), F("Touch the dots to calibrate"), FONT_LRG);
+ #endif
+
+ cmd.Cmd(CMD_CALIBRATE);
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void CalibrationScreen::onIdle() {
+ if(CLCD::CommandFifo::Is_Idle()) {
+ GOTO_SCREEN(StatusScreen);
+ }
+}
+
+/***************************** CALIBRATION REGISTERS SCREEN ****************************/
+
+void CalibrationRegistersScreen::onRefresh() {
+ const uint32_t T_Transform_A = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_A);
+ const uint32_t T_Transform_B = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_B);
+ const uint32_t T_Transform_C = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_C);
+ const uint32_t T_Transform_D = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_D);
+ const uint32_t T_Transform_E = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_E);
+ const uint32_t T_Transform_F = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_F);
+ char b[20];
+
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+ cmd.Cmd_Clear_Color(Theme::background);
+ cmd.Cmd_Clear(1,1,1);
+
+ #define MARGIN_T 5
+ #define GRID_ROWS 7
+ #define GRID_COLS 2
+ BTN_TAG(0)
+ RGB(transformA) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("TOUCH TRANSFORM_A"), 28, OPT_3D);
+ RGB(transformB) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("TOUCH TRANSFORM_B"), 28, OPT_3D);
+ RGB(transformC) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("TOUCH TRANSFORM_C"), 28, OPT_3D);
+ RGB(transformD) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("TOUCH TRANSFORM_D"), 28, OPT_3D);
+ RGB(transformE) BTN( BTN_POS(1,5), BTN_SIZE(1,1), F("TOUCH TRANSFORM_E"), 28, OPT_3D);
+ RGB(transformF) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F("TOUCH TRANSFORM_F"), 28, OPT_3D);
+
+ RGB(transformVal) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
+ RGB(transformVal) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
+ RGB(transformVal) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
+ RGB(transformVal) BTN( BTN_POS(2,4), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
+ RGB(transformVal) BTN( BTN_POS(2,5), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
+ RGB(transformVal) BTN( BTN_POS(2,6), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
+
+ sprintf(b, "0x%08lX", T_Transform_A); BTX( BTN_POS(2,1), BTN_SIZE(1,1), b, 28);
+ sprintf(b, "0x%08lX", T_Transform_B); BTX( BTN_POS(2,2), BTN_SIZE(1,1), b, 28);
+ sprintf(b, "0x%08lX", T_Transform_C); BTX( BTN_POS(2,3), BTN_SIZE(1,1), b, 28);
+ sprintf(b, "0x%08lX", T_Transform_D); BTX( BTN_POS(2,4), BTN_SIZE(1,1), b, 28);
+ sprintf(b, "0x%08lX", T_Transform_E); BTX( BTN_POS(2,5), BTN_SIZE(1,1), b, 28);
+ sprintf(b, "0x%08lX", T_Transform_F); BTX( BTN_POS(2,6), BTN_SIZE(1,1), b, 28);
+
+ #define GRID_COLS 3
+
+ BTN_TAG(1) RGB(navi_btn) BTN( BTN_POS(3,7), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
+
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void CalibrationRegistersScreen::onTouchStart(uint8_t tag) {
+ switch(tag) {
+ case 1: GOTO_PREVIOUS(); return;
+ }
+}
+
+/*************************** GENERIC VALUE ADJUSTMENT SCREEN ******************************/
+
+void ValueAdjusters::static_heading(progmem_str heading) {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd_Clear_Color(Theme::adjust_bg);
+ cmd.Cmd_Clear(1,1,1);
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_COLS 6
+ #define GRID_ROWS 9
+ #define EDGE_R 20
+ #else
+ #define GRID_COLS 9
+ #define GRID_ROWS 6
+ #define EDGE_R 40
+ #endif
+
+ #if defined(LCD_PORTRAIT)
+ BTN_TAG( 0) RGB(adjust_bg) BTN( BTN_POS(1,1), BTN_SIZE(6,1), heading, FONT_MED, OPT_FLAT);
+ BTN_TAG( 0) RGB(adjust_bg) BTN( BTN_POS(1,7), BTN_SIZE(2,1), F("Increment:"), FONT_SML, OPT_FLAT);
+
+ BTN_TAG(20) TOGGLE(increment == 0.1 ) BTN( BTN_POS(3,7), BTN_SIZE(1,1), F("0.1"), FONT_MED, OPT_3D);
+ BTN_TAG(21) TOGGLE(increment == 1. ) BTN( BTN_POS(4,7), BTN_SIZE(1,1), F("1"), FONT_MED, OPT_3D);
+ BTN_TAG(22) TOGGLE(increment == 10. ) BTN( BTN_POS(5,7), BTN_SIZE(1,1), F("10"), FONT_MED, OPT_3D);
+ BTN_TAG(23) TOGGLE(increment == 100.) BTN( BTN_POS(6,7), BTN_SIZE(1,1), F("100"), FONT_MED, OPT_3D);
+
+ #define EDGE_R 0
+ #define GRID_COLS 4
+ BTN_TAG(1) RGB(navi_btn) BTN( BTN_POS(1,9), BTN_SIZE(4,1), F("Back"), MENU_BTN_STYLE);
+ #else
+ BTN_TAG( 0) RGB(adjust_bg) BTN( BTN_POS(3,1), BTN_SIZE(4,1), heading, FONT_MED, OPT_FLAT);
+
+ BTN_TAG( 0) RGB(adjust_bg) BTN( BTN_POS(8,1), BTN_SIZE(2,1), F("Increment"), FONT_MED, OPT_FLAT);
+
+ BTN_TAG(20) TOGGLE(increment == 0.1 ) BTN( BTN_POS(8,2), BTN_SIZE(1,1), F("0.1"), FONT_MED, OPT_3D);
+ BTN_TAG(21) TOGGLE(increment == 1. ) BTN( BTN_POS(9,2), BTN_SIZE(1,1), F("1"), FONT_MED, OPT_3D);
+ BTN_TAG(22) TOGGLE(increment == 10. ) BTN( BTN_POS(8,3), BTN_SIZE(2,1), F("10"), FONT_MED, OPT_3D);
+ BTN_TAG(23) TOGGLE(increment == 100.) BTN( BTN_POS(8,4), BTN_SIZE(2,1), F("100"), FONT_MED, OPT_3D);
+
+ #define EDGE_R 0
+
+ #define MARGIN_T 15
+ #define GRID_COLS 4
+ BTN_TAG(1) RGB(navi_btn) BTN( BTN_POS(1,6), BTN_SIZE(4,1), F("Back"), MENU_BTN_STYLE);
+ #define MARGIN_T 5
+ #endif
+
+ cmd.Cmd_Execute();
+}
+
+void ValueAdjusters::static_value(int line, progmem_str label) {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_COLS 6
+ #define GRID_ROWS 9
+ #define EDGE_R 20
+ #else
+ #define GRID_COLS 9
+ #define GRID_ROWS 6
+ #define EDGE_R 40
+ #endif
+
+ BTN_TAG( 0) BTN( BTN_POS(3,line+1), BTN_SIZE(2,1), F(""), FONT_SML, OPT_FLAT);
+ BTN_TAG( 0) RGB(adjust_bg) BTN( BTN_POS(1,line+1), BTN_SIZE(2,1), label, FONT_SML, OPT_FLAT);
+ BTN_TAG(2*line ) RGB(incr_btn) BTN( BTN_POS(5,line+1), BTN_SIZE(1,1), F("-"), FONT_MED, OPT_3D);
+ BTN_TAG(2*line + 1) RGB(incr_btn) BTN( BTN_POS(6,line+1), BTN_SIZE(1,1), F("+"), FONT_MED, OPT_3D);
+
+ #define EDGE_R 0
+
+ cmd.Cmd_Execute();
+}
+
+void ValueAdjusters::dynamic_value(int line, float value, progmem_str units) {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ #define MARGIN_T 5
+
+ #if defined(LCD_PORTRAIT)
+ #define GRID_COLS 6
+ #define GRID_ROWS 9
+ #define EDGE_R 20
+ #else
+ #define GRID_COLS 9
+ #define GRID_ROWS 6
+ #define EDGE_R 40
+ #endif
+
+ BTN_TAG( 0)
+
+ char b[255];
+ dtostrf(value, 5, 1, b);
+ strcat_P(b, PSTR(" "));
+ strcat_P(b, (const char*) units);
+ BTX( BTN_POS(3,line+1), BTN_SIZE(2,1), b, FONT_SML);
+
+ #define EDGE_R 0
+
+ cmd.Cmd_Execute();
+}
+
+void ValueAdjusters::onTouchStart(uint8_t tag) {
+ switch(tag) {
+ case 1: GOTO_PREVIOUS(); return;
+ case 2 ... 9: current_screen.onTouchHeld(tag); return;
+ case 20: increment = 0.1; break;
+ case 21: increment = 1; break;
+ case 22: increment = 10; break;
+ case 23: increment = 100; break;
+ }
+ current_screen.onRefresh();
+}
+
+float ValueAdjusters::increment = 1;
+
+/******************************** MOVE AXIS SCREEN ******************************/
+
+void MoveAxisScreen::onRefresh() {
+ static CLCD::DLCache dlcache;
+
+ if(dlcache.hasData()) {
+ dlcache.append();
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+ cmd.Cmd_Execute();
+
+ ValueAdjusters::static_heading(F("Move Axis"));
+ RGB(x_axis) ValueAdjusters::static_value(1, F("X:"));
+ RGB(y_axis) ValueAdjusters::static_value(2, F("Y:"));
+ RGB(z_axis) ValueAdjusters::static_value(3, F("Z:"));
+ dlcache.store();
+ }
+
+ ValueAdjusters::dynamic_value(1, marlin_x_axis, F("mm"));
+ ValueAdjusters::dynamic_value(2, marlin_y_axis, F("mm"));
+ ValueAdjusters::dynamic_value(3, marlin_z_axis, F("mm"));
+
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void MoveAxisScreen::onTouchHeld(uint8_t tag) {
+ switch(tag) {
+ case 2: marlin_x_axis -= increment; break;
+ case 3: marlin_x_axis += increment; break;
+ case 4: marlin_y_axis -= increment; break;
+ case 5: marlin_y_axis += increment; break;
+ case 6: marlin_z_axis -= increment; break;
+ case 7: marlin_z_axis += increment; break;
+ }
+ onRefresh();
+}
+
+/******************************* TEMPERATURE SCREEN ******************************/
+
+void TemperatureScreen::onRefresh() {
+ static CLCD::DLCache dlcache;
+
+ if(dlcache.hasData()) {
+ dlcache.append();
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+
+ ValueAdjusters::static_heading(F("Temperature"));
+ RGB(x_axis) ValueAdjusters::static_value(1, F("Nozzle:"));
+ RGB(y_axis) ValueAdjusters::static_value(2, F("Bed:"));
+ RGB(z_axis) ValueAdjusters::static_value(3, F("Fan Speed:"));
+
+ cmd.Cmd_Execute();
+ dlcache.store();
+ }
+
+ ValueAdjusters::dynamic_value(1, marlin_e0_temp, F("C"));
+ ValueAdjusters::dynamic_value(2, marlin_bed_temp, F("C"));
+ ValueAdjusters::dynamic_value(3, marlin_fan_speed, F("%"));
+
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void TemperatureScreen::onTouchHeld(uint8_t tag) {
+ switch(tag) {
+ case 2: marlin_e0_temp -= increment; break;
+ case 3: marlin_e0_temp += increment; break;
+ case 4: marlin_bed_temp -= increment; break;
+ case 5: marlin_bed_temp += increment; break;
+ case 6: marlin_fan_speed -= increment; break;
+ case 7: marlin_fan_speed += increment; break;
+ }
+ onRefresh();
+}
+
+/******************************* STEPS SCREEN ******************************/
+
+void StepsScreen::onRefresh() {
+ static CLCD::DLCache dlcache;
+
+ if(dlcache.hasData()) {
+ dlcache.append();
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+
+ ValueAdjusters::static_heading(F("Steps/mm"));
+ RGB(x_axis) ValueAdjusters::static_value(1, F("X:"));
+ RGB(y_axis) ValueAdjusters::static_value(2, F("Y:"));
+ RGB(z_axis) ValueAdjusters::static_value(3, F("Z:"));
+ RGB(e_axis) ValueAdjusters::static_value(4, F("E:"));
+
+ cmd.Cmd_Execute();
+ dlcache.store();
+ }
+
+ ValueAdjusters::dynamic_value(1, marlin_x_steps, F(""));
+ ValueAdjusters::dynamic_value(2, marlin_y_steps, F(""));
+ ValueAdjusters::dynamic_value(3, marlin_z_steps, F(""));
+ ValueAdjusters::dynamic_value(4, marlin_e0_steps, F(""));
+
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void StepsScreen::onTouchHeld(uint8_t tag) {
+ switch(tag) {
+ case 2: marlin_x_steps -= increment; break;
+ case 3: marlin_x_steps += increment; break;
+ case 4: marlin_y_steps -= increment; break;
+ case 5: marlin_y_steps += increment; break;
+ case 6: marlin_z_steps -= increment; break;
+ case 7: marlin_z_steps += increment; break;
+ case 8: marlin_e0_steps -= increment; break;
+ case 9: marlin_e0_steps += increment; break;
+ }
+ onRefresh();
+}
+
+/***************************** Z-OFFSET SCREEN ***************************/
+
+void ZOffsetScreen::onRefresh() {
+ static CLCD::DLCache dlcache;
+
+ if(dlcache.hasData()) {
+ dlcache.append();
+ } else {
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(CMD_DLSTART);
+
+ ValueAdjusters::static_heading(F("Z Offset"));
+ RGB(z_axis) ValueAdjusters::static_value(2, F("Z Offset:"));
+
+ cmd.Cmd_Execute();
+ dlcache.store();
+ }
+
+ ValueAdjusters::dynamic_value(2, marlin_z_offset, F("mm"));
+
+ CLCD::CommandFifo cmd;
+ cmd.Cmd_Start();
+ cmd.Cmd(DL_DISPLAY);
+ cmd.Cmd(CMD_SWAP);
+ cmd.Cmd_Execute();
+}
+
+void ZOffsetScreen::onTouchHeld(uint8_t tag) {
+ switch(tag) {
+ case 4: marlin_z_offset -= increment; break;
+ case 5: marlin_z_offset += increment; break;
+ }
+ onRefresh();
+}
+
+/******************************** MAIN EVENT HANDLER *******************************/
+
+#define DISPLAY_UPDATE_INTERVAL 1000
+
+void lcd_init() {
+ CLCD::Init();
+ current_screen.start();
+}
+
+void lcd_update() {
+ const uint8_t NONE = 0xFF;
+ const uint8_t IGNORE = 0xFE;
+ static uint8_t pressed = NONE;
+ static uint32_t last_repeat = 0;
+ static uint32_t last_update = 0;
+
+ if(millis() - last_update > DISPLAY_UPDATE_INTERVAL) {
+ current_screen.onIdle();
+ last_update = millis();
+ }
+
+ // If the LCD is processing commands, don't check
+ // for tags since they may be changing and could
+ // cause spurious events.
+ if(!CLCD::CommandFifo::Is_Idle()) {
+ return;
+ }
+
+ CLCD::Test_Pulse();
+
+ const uint8_t tag = CLCD::Get_Tag();
+
+ if(tag == 0) {
+ // When the user lifts their finger, activate the onTouchEnd handler,
+ // except when pressed is IGNORE.
+ if(pressed == IGNORE) {
+ pressed = NONE;
+ }
+ else if(pressed != NONE) {
+ current_screen.onTouchEnd(pressed);
+ pressed = NONE;
+ }
+ }
+ else if(pressed == NONE) {
+ // When the user taps on a button, activate the onTouchStart handler
+ const uint8_t lastScreen = current_screen.getScreen();
+ current_screen.onTouchStart(tag);
+ last_repeat = millis();
+
+ #if defined(UI_FRAMEWORK_DEBUG)
+ Serial.print("Touch start: ");
+ Serial.println(tag);
+ #endif
+
+ if(lastScreen != current_screen.getScreen()) {
+ // In the case in which a touch event triggered a new screen to be
+ // drawn, we don't issue a touchEnd since it would be sent to the
+ // wrong screen.
+ pressed = IGNORE;
+ } else {
+ pressed = tag;
+ }
+ } else if(tag == pressed) {
+ // The user is holding down a button.
+ if((millis() - last_repeat) > 250) {
+ current_screen.onTouchHeld(tag);
+ last_repeat = millis();
+ }
+ }
+}
+
+inline bool lcd_hasstatus() { return true; }
+
+void lcd_setstatus(const char * const message, const bool persist = false) {
+ strncpy(lcd_status_message, message, STATUS_MESSAGE_BUFFER_LENGTH);
+}
+
+void lcd_setstatusPGM(const char * const message, int8_t level = 0) {
+ strncpy_P(lcd_status_message, message, STATUS_MESSAGE_BUFFER_LENGTH);
+}
+
+void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf_P(lcd_status_message, STATUS_MESSAGE_BUFFER_LENGTH, fmt, args);
+ va_end(args);
+}
+
+void lcd_setalertstatusPGM(const char * const message) {
+ lcd_setstatusPGM(message, 1);
+ GOTO_SCREEN(StatusScreen);
+}
+
+void lcd_buttons_update() {}
+inline void lcd_reset_alert_level() {}
+inline bool lcd_detected() { return true; }
+inline void lcd_refresh() {current_screen.onIdle();}
diff --git a/Marlin/AO_UI_Framework.h b/Marlin/AO_UI_Framework.h
new file mode 100644
index 000000000..e4d3becf7
--- /dev/null
+++ b/Marlin/AO_UI_Framework.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+ * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * To view a copy of the GNU General Public License, go to the following *
+ * location: . *
+ ****************************************************************************/
+
+ /********************** VIRTUAL DISPATCH DATA TYPE ******************************/
+
+// True virtual classes are extremely expensive on the Arduino
+// as the compiler stores the virtual function tables in RAM.
+// We invent a data type called ScreenRef that gives us
+// polymorphism by mapping an ID to virtual methods on various
+// classes. This works by keeping a table in PROGMEM of pointers
+// to static methods.
+
+#define DECL_SCREEN(className) { \
+ className::onStartup, \
+ className::onEntry, \
+ className::onExit, \
+ className::onIdle, \
+ className::onRefresh, \
+ className::onTouchStart, \
+ className::onTouchHeld, \
+ className::onTouchEnd \
+}
+
+#define GET_METHOD(type, method) reinterpret_cast(pgm_read_word_near(&functionTable[type].method##_ptr))
+#define SCREEN_TABLE PROGMEM const ScreenRef::table_t ScreenRef::functionTable[] =
+#define SCREEN_TABLE_POST const uint8_t ScreenRef::functionTableSize = sizeof(ScreenRef::functionTable)/sizeof(ScreenRef::functionTable[0]);
+
+class ScreenRef {
+ protected:
+ typedef void onStartup_func_t(void);
+ typedef void onEntry_func_t(void);
+ typedef void onExit_func_t(void);
+ typedef void onIdle_func_t(void);
+ typedef void onRefresh_func_t(void);
+ typedef void onTouchStart_func_t(uint8_t);
+ typedef void onTouchHeld_func_t(uint8_t);
+ typedef void onTouchEnd_func_t(uint8_t);
+
+ private:
+ typedef struct {
+ onStartup_func_t *onStartup_ptr;
+ onEntry_func_t *onEntry_ptr;
+ onExit_func_t *onExit_ptr;
+ onIdle_func_t *onIdle_ptr;
+ onRefresh_func_t *onRefresh_ptr;
+ onTouchStart_func_t *onTouchStart_ptr;
+ onTouchHeld_func_t *onTouchHeld_ptr;
+ onTouchEnd_func_t *onTouchEnd_ptr;
+ } table_t;
+
+ uint8_t type = 0;
+ static PROGMEM const table_t functionTable[];
+ static const uint8_t functionTableSize;
+
+ public:
+ uint8_t getType() {return type;}
+
+ void setType(uint8_t t) {
+ type = t;
+ }
+
+ void setScreen(onEntry_func_t onRefresh_ptr) {
+ for(uint8_t type = 0; type < functionTableSize; type++) {
+ if(GET_METHOD(type, onRefresh) == onRefresh_ptr) {
+ setType(type);
+ #if defined(UI_FRAMEWORK_DEBUG)
+ #if defined(SERIAL_PROTOCOLLNPAIR)
+ SERIAL_PROTOCOLLNPAIR("New screen: ",type);
+ #else
+ Serial.print("New screen: ");
+ Serial.println(type);
+ #endif
+ #endif
+ return;
+ }
+ }
+ #if defined(UI_FRAMEWORK_DEBUG)
+ #if defined(SERIAL_PROTOCOLLNPAIR)
+ SERIAL_PROTOCOLLNPAIR("Screen not found: ", (uint16_t) onRefresh_ptr);
+ #else
+ Serial.print("Screen not found: ");
+ Serial.println((uint16_t) onRefresh_ptr, HEX);
+ #endif
+ #endif
+ }
+
+ void onStartup() {GET_METHOD(type, onStartup)();}
+ void onEntry() {GET_METHOD(type, onEntry)();}
+ void onExit() {GET_METHOD(type, onExit)();}
+ void onIdle() {GET_METHOD(type, onIdle)();}
+ void onRefresh() {GET_METHOD(type, onRefresh)();}
+ void onTouchStart(uint8_t tag) {GET_METHOD(type, onTouchStart)(tag);}
+ void onTouchHeld(uint8_t tag) {GET_METHOD(type, onTouchHeld)(tag);}
+ void onTouchEnd(uint8_t tag) {GET_METHOD(type, onTouchEnd)(tag);}
+
+ void initializeAll() {
+ for(uint8_t type = 0; type < functionTableSize; type++) {
+ GET_METHOD(type, onStartup)();
+ }
+ }
+};
+
+/********************** SCREEN STACK ******************************/
+
+// To conserve dynamic memory, the screen stack is hard-coded to
+// have three values, allowing a menu of up to three levels.
+
+class ScreenStack : public ScreenRef {
+ private:
+ uint8_t stack[3];
+
+ public:
+ void start() {
+ initializeAll();
+ onEntry();
+ }
+
+ void push() {
+ stack[2] = stack[1];
+ stack[1] = stack[0];
+ stack[0] = getType();
+ }
+
+ void pop() {
+ setType(stack[0]);
+ stack[0] = stack[1];
+ stack[1] = stack[2];
+ stack[2] = 0;
+ }
+
+ void goTo(onEntry_func_t s) {
+ push();
+ onExit();
+ setScreen(s);
+ onEntry();
+ }
+
+ void goBack() {
+ pop();
+ onEntry();
+ }
+
+ uint8_t getScreen() {
+ return getType();
+ }
+} current_screen;
+
+/********************** BASE SCREEN CLASSS ******************************/
+
+/* UIScreen is the base class for all user interface screens.
+ */
+class UIScreen {
+ public:
+ static void onStartup() {}
+ static void onEntry() {current_screen.onRefresh();}
+ static void onExit() {}
+ static void onIdle() {}
+ static void onTouchStart(uint8_t) {}
+ static void onTouchHeld(uint8_t) {}
+ static void onTouchEnd(uint8_t) {}
+};
+
+#define GOTO_SCREEN(screen) current_screen.goTo(screen::onRefresh);
+#define GOTO_PREVIOUS() current_screen.goBack();
diff --git a/Marlin/AO_UI_Marlin_LCD_API.h b/Marlin/AO_UI_Marlin_LCD_API.h
new file mode 100644
index 000000000..2399e9a39
--- /dev/null
+++ b/Marlin/AO_UI_Marlin_LCD_API.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+ * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * To view a copy of the GNU General Public License, go to the following *
+ * location: . *
+ ****************************************************************************/
+
+class Marlin_LCD_API {
+ public:
+ typedef const __FlashStringHelper *progmem_str;
+
+ enum axis_t {
+ X,
+ Y,
+ Z,
+ E0,
+ E1
+ };
+
+ static const uint8_t extruderCount;
+ static const uint8_t fanCount;
+
+ static const float getActualTemp_celsius(const uint8_t extruder);
+ static const float getTargetTemp_celsius(const uint8_t extruder);
+ static const float getFan_percent(const uint8_t fan);
+
+ static const float getAxisPosition_mm(const axis_t axis);
+ static const float getAxisSteps_per_mm(const axis_t axis);
+ static const uint8_t getProgress_percent();
+ static const uint32_t getProgress_seconds_elapsed();
+ static const uint8_t getFeedRate_percent();
+ static const float getZOffset_mm();
+ static const bool isAxisPositionKnown(const axis_t axis);
+};
+
+#if defined(MSG_MARLIN)
+const uint8_t Marlin_LCD_API::extruderCount = EXTRUDERS;
+const uint8_t Marlin_LCD_API::fanCount = 1;
+
+const float Marlin_LCD_API::getActualTemp_celsius(const uint8_t extruder) {
+ if(extruder) {
+ thermalManager.degHotend(extruder-1);
+ } else {
+ thermalManager.degBed();
+ }
+}
+
+const float Marlin_LCD_API::getTargetTemp_celsius(const uint8_t extruder) {
+ if(extruder) {
+ thermalManager.degTargetHotend(extruder-1);
+ } else {
+ thermalManager.degTargetBed();
+ }
+}
+
+const float Marlin_LCD_API::getFan_percent(const uint8_t fan) {
+ return ((fanSpeeds[fan] + 1) * 100) / 256;
+}
+
+const float Marlin_LCD_API::getAxisPosition_mm(const Marlin_LCD_API::axis_t axis) {
+ switch(axis) {
+ case X: return current_position[X_AXIS]; break;
+ case Y: return current_position[Y_AXIS]; break;
+ case Z: return current_position[Z_AXIS]; break;
+ case E0: return current_position[E_AXIS]; break;
+ case E1: return current_position[E_AXIS+1]; break;
+ }
+}
+
+const float Marlin_LCD_API::getAxisSteps_per_mm(const Marlin_LCD_API::axis_t axis) {
+ return 0;
+}
+
+const uint8_t Marlin_LCD_API::getProgress_percent() {
+ #if ENABLED(SDSUPPORT)
+ return card.percentDone();
+ #endif
+}
+
+const uint32_t Marlin_LCD_API::getProgress_seconds_elapsed() {
+ const duration_t elapsed = print_job_timer.duration();
+ return elapsed.value;
+}
+
+const uint8_t Marlin_LCD_API::getFeedRate_percent() {
+ return feedrate_percentage;
+}
+
+const bool Marlin_LCD_API::isAxisPositionKnown(const axis_t axis) {
+ switch(axis) {
+ case X: return axis_known_position[X_AXIS]; break;
+ case Y: return axis_known_position[Y_AXIS]; break;
+ case Z: return axis_known_position[Z_AXIS]; break;
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Marlin/Conditionals_LulzBot.h b/Marlin/Conditionals_LulzBot.h
index 0ca7868be..ab20b058b 100644
--- a/Marlin/Conditionals_LulzBot.h
+++ b/Marlin/Conditionals_LulzBot.h
@@ -13,7 +13,7 @@
* got disabled.
*/
-#define LULZBOT_FW_VERSION ".4" // Change this with each update
+#define LULZBOT_FW_VERSION ".5" // Change this with each update
#if ( \
!defined(LULZBOT_Gladiola_Mini) && \
@@ -21,7 +21,9 @@
!defined(LULZBOT_Juniper_TAZ5) && \
!defined(LULZBOT_Oliveoil_TAZ6) && \
!defined(LULZBOT_Hibiscus_Mini2) && \
- !defined(LULZBOT_Quiver_TAZ7) \
+ !defined(LULZBOT_Hibiscus_Mini2_CLCD) && \
+ !defined(LULZBOT_Quiver_TAZ7) && \
+ !defined(LULZBOT_Quiver_TAZ7_CLCD) \
) || ( \
!defined(TOOLHEAD_Gladiola_SingleExtruder) && \
!defined(TOOLHEAD_Albatross_Flexystruder) && \
@@ -120,6 +122,26 @@
#define LULZBOT_USE_EXPERIMENTAL_FEATURES
#endif
+#if defined(LULZBOT_Hibiscus_Mini2_CLCD)
+ #define LULZBOT_CUSTOM_MACHINE_NAME "LulzBot Mini 2"
+ #define LULZBOT_LCD_MACHINE_NAME "Mini 2"
+ #define LULZBOT_IS_MINI
+ #define LULZBOT_MINI_BED
+ #define LULZBOT_USE_EINSYRAMBO
+ #define LULZBOT_USE_EINSY_RETRO
+ #define LULZBOT_USE_TOUCH_UI
+ #define LULZBOT_TWO_PIECE_BED
+ #define LULZBOT_USE_AUTOLEVELING
+ #define LULZBOT_SENSORLESS_HOMING
+ #define LULZBOT_USE_TMC_STEALTHCHOP_Z
+ #define LULZBOT_USE_Z_BELT
+ #define LULZBOT_BAUDRATE 250000
+ #define LULZBOT_PRINTCOUNTER
+ #define LULZBOT_USE_32_MICROSTEPS_ON_Z
+ #define LULZBOT_UUID "e5502411-d46d-421d-ba3a-a20126d7930f"
+ #define LULZBOT_USE_EXPERIMENTAL_FEATURES
+#endif
+
#if defined(LULZBOT_Quiver_TAZ7)
#define LULZBOT_CUSTOM_MACHINE_NAME "LulzBot TAZ 7"
#define LULZBOT_LCD_MACHINE_NAME "TAZ 7"
@@ -139,6 +161,24 @@
#define LULZBOT_USE_EXPERIMENTAL_FEATURES
#endif
+#if defined(LULZBOT_Quiver_TAZ7_CLCD)
+ #define LULZBOT_CUSTOM_MACHINE_NAME "LulzBot TAZ 7"
+ #define LULZBOT_LCD_MACHINE_NAME "TAZ 7"
+ #define LULZBOT_IS_TAZ
+ #define LULZBOT_TAZ_BED
+ #define LULZBOT_TWO_PIECE_BED
+ #define LULZBOT_USE_TOUCH_UI
+ #define LULZBOT_USE_AUTOLEVELING
+ #define LULZBOT_USE_MIN_ENDSTOPS
+ #define LULZBOT_USE_MAX_ENDSTOPS
+ #define LULZBOT_USE_NORMALLY_CLOSED_ENDSTOPS
+ #define LULZBOT_USE_Z_BELT
+ #define LULZBOT_BAUDRATE 250000
+ #define LULZBOT_PRINTCOUNTER
+ #define LULZBOT_UUID "a952577d-8722-483a-999d-acdc9e772b7b"
+ #define LULZBOT_USE_EXPERIMENTAL_FEATURES
+#endif
+
/****************************** DEBUGGING OPTIONS *******************************/
//#define LULZBOT_TMC_SHOW_CURRENT_ADJUSTMENTS
@@ -1875,6 +1915,11 @@
#define LULZBOT_LCD_CLEAR_DECL
#endif
+#if defined(LULZBOT_USE_TOUCH_UI)
+extern void lcd_update();
+extern void lcd_buttons_update();
+#endif
+
/***************************** CUSTOM SPLASH SCREEN *****************************/
#define LULZBOT_CUSTOM_BOOTSCREEN() \
diff --git a/Marlin/Configuration_LulzBot.h b/Marlin/Configuration_LulzBot.h
index 972317d67..b13155c1c 100644
--- a/Marlin/Configuration_LulzBot.h
+++ b/Marlin/Configuration_LulzBot.h
@@ -13,9 +13,11 @@
Gladiola_Mini // Lulzbot Mini (Gladiola)
Gladiola_MiniLCD // Lulzbot Mini (Gladiola w/ LCD)
Hibiscus_Mini2 // Lulzbot Mini 2 (Hibiscus)
+ Hibiscus_Mini2_CLCD // Lulzbot Mini 2 (Hibiscus w/ CLCD)
Juniper_TAZ5 // Lulzbot TAZ 5 (Juniper, Juniperberry, Juniperbush)
Oliveoil_TAZ6 // Lulzbot TAZ 6 (Oliveoil)
Quiver_TAZ7 // Lulzbot TAZ 7 (Quiver)
+ Quiver_TAZ7_CLCD // Lulzbot TAZ 7 (Quiver w/ CLCD)
Mini Toolhead Choices:
Gladiola_SingleExtruder // Standard Single Extruder (Gladiola)
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 29c04b2ee..f2f137f2c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -348,6 +348,21 @@
float coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
#endif
+#if defined(LULZBOT_USE_TOUCH_UI)
+#define IS_FT810
+#define LCD_PORTRAIT
+#define LCD_UPSIDE_DOWN
+//#define UI_FRAMEWORK_DEBUG
+#include "AO_UI_Marlin_LCD_API.h"
+#include "AO_UI_Framework.h"
+#include "AO_FT810_Constants.h"
+#include "AO_FT810_Functions.h"
+#include "AO_FT810_Pins.h"
+#include "AO_FT810_SPI.h"
+#include "AO_FT810_UI_Bitmaps.h"
+#include "AO_FT810_UI_Screens.h"
+#endif
+
bool Running = true;
uint8_t marlin_debug_flags = DEBUG_NONE;
diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h
index ab2ce15a3..a8ca159fb 100644
--- a/Marlin/ultralcd.h
+++ b/Marlin/ultralcd.h
@@ -185,8 +185,7 @@
extern uint8_t progress_bar_percent;
#endif
-#else // no LCD
-
+#elif !defined(LULZBOT_USE_TOUCH_UI) // no LCD
inline void lcd_update() {}
inline void lcd_init() {}
inline bool lcd_hasstatus() { return false; }
@@ -198,7 +197,6 @@
inline void lcd_reset_alert_level() {}
inline bool lcd_detected() { return true; }
inline void lcd_refresh() {}
-
#endif // ULTRA_LCD
#define LCD_MESSAGEPGM(x) lcd_setstatusPGM(PSTR(x))