First implementation of touch UI in Marlin.

- Status screen works and you can navigate the menus, but the menus
are non-functional.
master
Marcio Teixeira 7 years ago
parent e9ed3e78b6
commit 0e03d1ac3f

@ -0,0 +1,712 @@
/***********
* 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: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/****************************************************************************
* 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
const uint32_t RAM_G_SIZE = 256l*1024l; // 256k
}
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
const uint32_t RAM_G_SIZE = 1024l*1024l; // 1024k
}
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;
}
namespace FTDI {
enum effect_t {
SILENCE = 0x00,
SQUARE_WAVE = 0x01,
SINE_WAVE = 0x02,
SAWTOOTH_WAVE = 0x03,
TRIANGLE_WAVE = 0x04,
BEEPING = 0x05,
ALARM = 0x06,
WARBLE = 0x07,
CAROUSEL = 0x08,
SHORT_PIPS_1 = 0x10,
SHORT_PIPS_2 = 0x11,
SHORT_PIPS_3 = 0x12,
SHORT_PIPS_4 = 0x13,
SHORT_PIPS_5 = 0x14,
SHORT_PIPS_6 = 0x15,
SHORT_PIPS_7 = 0x16,
SHORT_PIPS_8 = 0x17,
SHORT_PIPS_9 = 0x18,
SHORT_PIPS_10 = 0x19,
SHORT_PIPS_11 = 0x1A,
SHORT_PIPS_12 = 0x1B,
SHORT_PIPS_13 = 0x1C,
SHORT_PIPS_14 = 0x1D,
SHORT_PIPS_15 = 0x1E,
SHORT_PIPS_16 = 0x1F,
DTMF_POUND = 0x23,
DTMF_STAR = 0x2C,
DTMF_0 = 0x30,
DTMF_1 = 0x31,
DTMF_2 = 0x32,
DTMF_3 = 0x33,
DTMF_4 = 0x34,
DTMF_5 = 0x35,
DTMF_6 = 0x36,
DTMF_7 = 0x37,
DTMF_8 = 0x38,
DTMF_9 = 0x39,
HARP = 0x40,
XYLOPHONE = 0x41,
TUBA = 0x42,
GLOCKENSPIEL = 0x43,
ORGAN = 0x44,
TRUMPET = 0x45,
PIANO = 0x46,
CHIMES = 0x47,
MUSIC_BOX = 0x48,
BELL = 0x49,
CLICK = 0x50,
SWITCH = 0x51,
COWBELL = 0x52,
NOTCH = 0x53,
HIHAT = 0x54,
KICKDRUM = 0x55,
POP = 0x56,
CLACK = 0x57,
CHACK = 0x58,
MUTE = 0x60,
UNMUTE = 0x61
};
}
// If LCD_IS_FT800 is defined, then copy the FT800 namespace into the FTDI namespace
// If LCD_IS_FT810 is defined, then copy the FT810 namespace into the FTDI namespace
#if defined(LCD_IS_FT800)
namespace FTDI {
using namespace FT800;
}
#elif defined(LCD_IS_FT810)
namespace FTDI {
using namespace FT810;
}
#endif
#endif // _AO_FT810_H

@ -0,0 +1,863 @@
/*********************
* 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: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/****************************************************************************
* 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 *
* 35000 Static DL Space (FT800) *
* F5000 Static DL Space (FT810) *
**************************************************/
#ifndef _AO_FT810_FUNC_H
#define _AO_FT810_FUNC_H
#if defined(LCD_IS_FT800)
#define DL_CACHE_START 0x035000
#else
#define DL_CACHE_START 0x0F5000
#endif
// Uncomment the following to disable the DL caching mechanism
//#define DL_CACHE_DISABLED
#if defined(LCD_800x480)
using namespace FTDI_LCD_800x480;
#elif defined(LCD_480x272)
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;
class SoundPlayer;
class DLCache;
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);
}
}
/******************* FT800/810 Graphic Commands *********************************/
class CLCD::CommandFifo {
protected:
static uint32_t getRegCmdWrite();
static uint32_t getRegCmdRead();
#if defined(LCD_IS_FT800)
static uint32_t command_write_ptr;
template <class T> void _write_unaligned(T data, uint16_t len);
#else
uint32_t getRegCmdBSpace();
#endif
void Cmd_Start(void);
public:
template <class T> void write(T data, uint16_t len);
public:
CommandFifo() {Cmd_Start();}
static void Cmd_Reset (void);
static bool Cmd_Is_Idle();
static void Cmd_Wait_Until_Idle();
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<typename T> 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<typename T> 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<typename T> 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);
};
#if defined(LCD_IS_FT800)
uint32_t CLCD::CommandFifo::command_write_ptr = 0xFFFFFFFFul;
#endif
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<typename T> 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<typename T> 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();
* }
*/
class CLCD::DLCache {
private:
static uint16_t dl_free;
uint16_t dl_addr = 0;
uint16_t dl_size = 0;
public:
bool hasData();
void store();
void append();
};
uint16_t CLCD::DLCache::dl_free = 0;
bool CLCD::DLCache::hasData() {
return dl_size != 0;
}
void CLCD::DLCache::store() {
#if !defined(DL_CACHE_DISABLED)
CLCD::CommandFifo cmd;
// Execute any commands already in the FIFO
cmd.Cmd_Execute();
cmd.Cmd_Wait_Until_Idle();
// Figure out how long the display list is
dl_size = Mem_Read32(REG_CMD_DL) & 0x1FFF;
dl_addr = dl_free;
if((dl_addr + dl_size) > RAM_G_SIZE) {
// Not enough memory to cache the display list.
dl_addr = 0;
dl_size = 0;
#if defined(UI_FRAMEWORK_DEBUG)
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLLNPAIR("Not enough space in GRAM to cache display list, free space: ", RAM_G_SIZE - dl_free);
#else
Serial.print(F("Not enough space in GRAM to cache display list, free space:"));
Serial.println(RAM_G_SIZE - dl_free);
#endif
#endif
} else {
#if defined(UI_FRAMEWORK_DEBUG)
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLPAIR("Saving DL to RAMG cache, bytes: ", dl_size);
SERIAL_PROTOCOLPAIR(" (Free space: ", RAM_G_SIZE - dl_free);
SERIAL_PROTOCOLLNPGM(")");
#else
Serial.print(F("Saving DL to RAMG cache, bytes: "));
Serial.println(dl_size);
Serial.print(F(" (Free space: "));
Serial.println(RAM_G_SIZE - dl_free);
Serial.print(F(")"));
#endif
#endif
cmd.Cmd_Mem_Cpy(DL_CACHE_START + dl_addr, RAM_DL, dl_size);
cmd.Cmd_Execute();
dl_free += dl_size;
}
#endif
}
void CLCD::DLCache::append() {
CLCD::CommandFifo cmd;
cmd.Cmd_Append(DL_CACHE_START + dl_addr, dl_size);
#if defined(UI_FRAMEWORK_DEBUG)
cmd.Cmd_Execute();
cmd.Cmd_Wait_Until_Idle();
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLPAIR("Appending to DL from RAMG cache, bytes: ", dl_size);
SERIAL_PROTOCOLPAIR(" (REG_CMD_DL: ", Mem_Read32(REG_CMD_DL));
SERIAL_PROTOCOLLNPGM(")");
#else
Serial.print(F("Appending to DL from RAMG cache, bytes: "));
Serial.print(dl_size);
Serial.print(" (REG_CMD_DL: ");
Serial.print(Mem_Read32(REG_CMD_DL));
Serial.println(")");
#endif
#endif
}
/******************* LCD INITIALIZATION ************************/
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 LCD_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);
uint8_t 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_PROTOCOLLNPGM)
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(LCD_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::Cmd_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);
}
/******************* SOUND HELPER CLASS ************************/
class CLCD::SoundPlayer {
public:
struct sound_t {
effect_t effect; // The sound effect number
uint8_t note; // The MIDI note value
uint8_t sixteenths; // Duration of note, in sixteeths of a second, or zero to play to completion
};
private:
const sound_t *sequence;
uint32_t next;
public:
static const uint8_t MIDDLE_C = 60; // C4
static void setVolume(uint8_t volume);
static void play(effect_t effect, uint8_t note = MIDDLE_C);
static bool soundPlaying();
void play(const sound_t* seq);
void onIdle();
};
void CLCD::SoundPlayer::setVolume(uint8_t vol) {
CLCD::Mem_Write8(REG_VOL_SOUND, vol);
}
void CLCD::SoundPlayer::play(effect_t effect, uint8_t note) {
CLCD::Mem_Write16(REG_SOUND, (note << 8) | effect);
CLCD::Mem_Write8( REG_PLAY, 1);
#if defined(UI_FRAMEWORK_DEBUG)
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLPAIR("Playing note ", note);
SERIAL_PROTOCOLLNPAIR(", instrument ", effect);
#endif
#endif
}
void CLCD::SoundPlayer::play(const sound_t* seq) {
sequence = seq;
next = 0;
}
bool CLCD::SoundPlayer::soundPlaying() {
return CLCD::Mem_Read8( REG_PLAY ) & 0x1;
}
void CLCD::SoundPlayer::onIdle() {
if(!sequence) return;
const bool readyForNextNote = next != 0 ? (millis() > next) : !soundPlaying();
if(readyForNextNote) {
const effect_t fx = effect_t(pgm_read_byte_near(&sequence->effect));
const uint8_t nt = pgm_read_byte_near(&sequence->note);
const uint16_t ms = uint32_t(pgm_read_byte_near(&sequence->sixteenths)) * 1000 / 16;
if(ms == 0 && fx == SILENCE && nt == 0) {
sequence = 0;
} else {
next = ms ? (millis() + ms) : 0;
play(fx, nt != 0 ? nt : MIDDLE_C);
sequence++;
}
}
}
#endif // _AO_FT810_FUNC_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 <http://www.gnu.org/licenses/>.
*
*/
#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

@ -0,0 +1,414 @@
/*********************
* 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: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#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(100);
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::Cmd_Is_Idle() {
return getRegCmdRead() == getRegCmdWrite();
}
void CLCD::CommandFifo::Cmd_Wait_Until_Idle() {
#if defined(UI_FRAMEWORK_DEBUG)
const uint32_t startTime = millis();
#endif
do {
#if defined(UI_FRAMEWORK_DEBUG)
if(millis() - startTime > 3) {
#if defined (SERIAL_PROTOCOLLNPGM)
SERIAL_PROTOCOLLNPGM("Timeout on CommandFifo::Wait_Until_Idle()");
#else
Serial.println(F("Timeout on CommandFifo::Wait_Until_Idle()"));
#endif
break;
}
#endif
} while(!Cmd_Is_Idle());
}
#if defined(LCD_IS_FT800)
void CLCD::CommandFifo::Cmd_Start() {
if(command_write_ptr == 0xFFFFFFFFul) {
command_write_ptr = getRegCmdWrite();
}
}
void CLCD::CommandFifo::Cmd_Execute() {
if(command_write_ptr != 0xFFFFFFFFul) {
Mem_Write32(REG_CMD_WRITE, command_write_ptr);
}
}
void CLCD::CommandFifo::Cmd_Reset() {
Mem_Write32(REG_CMD_WRITE, 0x00000000);
Mem_Write32(REG_CMD_READ, 0x00000000);
command_write_ptr = 0xFFFFFFFFul;
};
template <class T> 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;
#if defined(UI_FRAMEWORK_DEBUG)
if(command_write_ptr == 0xFFFFFFFFul) {
#if defined (SERIAL_PROTOCOLLNPGM)
SERIAL_PROTOCOLLNPGM("Attempt to write to FIFO before CommandFifo::Cmd_Start().");
#else
Serial.println(F("Attempt to write to FIFO before CommandFifo::Cmd_Start()."));
#endif
}
#endif
/* 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 <class T> 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::Cmd_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 <class T> 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

@ -0,0 +1,169 @@
/***************************
* 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: <http://www.gnu.org/licenses/>. *
****************************************************************************/
// 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 + 9000,
.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};

@ -0,0 +1,1350 @@
/****************************************************************************
* 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: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#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
#if defined(LCD_800x480)
#define MARGIN_L 5
#define MARGIN_R 5
#define MARGIN_T 5
#define MARGIN_B 5
#else
#define MARGIN_L 3
#define MARGIN_R 3
#define MARGIN_T 3
#define MARGIN_B 3
#endif
// 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(rgb);
#define THEME(color) cmd.Cmd_Set_Foreground_Color(Theme::color);
#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 {
public:
static void onEntry();
static void onRefresh();
static void onTouchStart(uint8_t tag);
static void onIdle();
};
class StatusScreen : public UIScreen {
private:
static void static_axis_position();
static void static_temperature();
static void static_progress();
static void static_interaction_buttons();
static void dynamic_axis_position();
static void dynamic_temperature();
static void dynamic_progress();
static void dynamic_status_message();
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 {
private:
static uint8_t increment;
static void draw_increment_btn(const uint8_t tag, uint8_t decimals);
protected:
struct heading_t {
const char *label;
uint8_t decimals;
void static_parts() const;
void dynamic_parts() const;
};
struct adjuster_t {
uint8_t line;
const char *label;
const char *units;
uint32_t color;
uint8_t decimals;
void static_parts() const;
void dynamic_parts(float value) const;
};
static float getIncrement();
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;
const float icon_scale = 0.7;
#else
const int16_t font_small = 27;
const int16_t font_medium = 28;
const int16_t font_large = 30;
const float icon_scale = 0.6;
#endif
#endif
const effect_t press_sound = CHACK;
const effect_t repeat_sound = CHACK;
const effect_t unpress_sound = POP;
};
/******************************** BOOT SCREEN ****************************/
void BootScreen::onRefresh() {
CLCD::CommandFifo cmd;
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.Cmd_Wait_Until_Idle();
CLCD::Turn_On_Backlight();
CLCD::SoundPlayer::setVolume(255);
}
void BootScreen::onIdle() {
GOTO_SCREEN(CalibrationScreen);
}
/******************************** ABOUT SCREEN ****************************/
CLCD::SoundPlayer sound;
const PROGMEM CLCD::SoundPlayer::sound_t chimes[] = {
{CHIMES, 55, 13},
{CHIMES, 64, 13},
{CHIMES, 60, 19}
};
const PROGMEM CLCD::SoundPlayer::sound_t samples[] = {
{HARP},
{XYLOPHONE},
{TUBA},
{GLOCKENSPIEL},
{ORGAN},
{TRUMPET},
{PIANO},
{CHIMES},
{MUSIC_BOX},
{BELL},
{CLICK},
{SWITCH},
{COWBELL},
{NOTCH},
{HIHAT},
{KICKDRUM},
{SWITCH},
{POP},
{CLACK},
{CHACK},
{SILENCE}
};
void AboutScreen::onEntry() {
UIScreen::onEntry();
CLCD::Mem_Write8(REG_VOL_SOUND, 0xFF);
sound.play(chimes);
}
void AboutScreen::onRefresh() {
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
cmd.Cmd_Clear_Color(Theme::about_bg);
cmd.Cmd_Clear(1,1,1);
#define GRID_COLS 4
#define GRID_ROWS 8
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);
BTX( BTN_POS(1,5), BTN_SIZE(4,1), Marlin_LCD_API::getFirmwareName(), FONT_LRG);
BTN_TAG(1) THEME(about_btn) BTN( BTN_POS(2,7), 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::onIdle() {
sound.onIdle();
}
/*********************************** STATUS SCREEN ******************************/
#if defined(LCD_PORTRAIT)
#define GRID_ROWS 9
#define GRID_COLS 3
#else
#define GRID_ROWS 8
#define GRID_COLS 3
#endif
void StatusScreen::static_axis_position() {
CLCD::CommandFifo cmd;
#if defined(LCD_PORTRAIT)
THEME(axis_label) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
THEME(axis_label) BTN( BTN_POS(1,6), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
THEME(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);
THEME(x_axis) BTN( BTN_POS(2,5), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
THEME(y_axis) BTN( BTN_POS(2,6), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
THEME(z_axis) BTN( BTN_POS(2,7), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
#else
THEME(axis_label) BTN( BTN_POS(1,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
THEME(axis_label) BTN( BTN_POS(2,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
THEME(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);
THEME(x_axis) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
THEME(y_axis) BTN( BTN_POS(2,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
THEME(z_axis) BTN( BTN_POS(3,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
#endif
}
void StatusScreen::dynamic_axis_position() {
CLCD::CommandFifo cmd;
char x_str[15];
char y_str[15];
char z_str[15];
dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::X), 5, 1, x_str);
dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Y), 5, 1, y_str);
dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Z), 5, 1, z_str);
strcat_P(x_str, PSTR(" mm"));
strcat_P(y_str, PSTR(" mm"));
strcat_P(z_str, PSTR(" mm"));
#if defined(LCD_PORTRAIT)
BTX( BTN_POS(2,5), BTN_SIZE(2,1), x_str, FONT_MED);
BTX( BTN_POS(2,6), BTN_SIZE(2,1), y_str, FONT_MED);
BTX( BTN_POS(2,7), BTN_SIZE(2,1), z_str, FONT_MED);
#else
BTX( BTN_POS(1,6), BTN_SIZE(1,1), x_str, FONT_MED);
BTX( BTN_POS(2,6), BTN_SIZE(1,1), y_str, FONT_MED);
BTX( BTN_POS(3,6), BTN_SIZE(1,1), z_str, FONT_MED);
#endif
//#define MARGIN_T 5
}
#if defined(LCD_PORTRAIT)
#define GRID_COLS 8
#else
#define GRID_COLS 12
#endif
void StatusScreen::static_temperature() {
CLCD::CommandFifo cmd;
BTN_TAG(0)
#if defined(LCD_PORTRAIT)
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(4,2), F(""), FONT_SML, OPT_FLAT);
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(8,1), F(""), FONT_SML, OPT_FLAT);
THEME(fan_speed) BTN( BTN_POS(5,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
THEME(progress) BTN( BTN_POS(1,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
THEME(progress) BTN( BTN_POS(5,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
#else
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(4,2), F(""), FONT_SML, OPT_FLAT);
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(8,1), F(""), FONT_SML, OPT_FLAT);
THEME(fan_speed) BTN( BTN_POS(5,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
THEME(progress) BTN( BTN_POS(9,1), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
THEME(progress) BTN( BTN_POS(9,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
#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);
// 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);
}
#define ROUND(val) uint16_t((val)+0.5)
void StatusScreen::dynamic_temperature() {
CLCD::CommandFifo cmd;
char e0_str[15];
char e1_str[15];
char bed_str[15];
char fan_str[15];
sprintf_P(
fan_str,
PSTR("%-3d %%"),
Marlin_LCD_API::getFan_percent(0)
);
sprintf_P(
bed_str,
PSTR("%-3d / %-3d " ),
ROUND(Marlin_LCD_API::getActualTemp_celsius(0)),
ROUND(Marlin_LCD_API::getTargetTemp_celsius(0))
);
sprintf_P(
e0_str,
PSTR("%-3d / %-3d C"),
ROUND(Marlin_LCD_API::getActualTemp_celsius(1)),
ROUND(Marlin_LCD_API::getTargetTemp_celsius(1))
);
#if EXTRUDERS == 2
sprintf_P(
e1_str,
PSTR("%-3d / %-3d C"),
ROUND(Marlin_LCD_API::getActualTemp_celsius(2)),
ROUND(Marlin_LCD_API::getTargetTemp_celsius(2))
);
#else
strcpy_P(
e1_str,
PSTR("-")
);
#endif
BTX( BTN_POS(2,1), BTN_SIZE(3,1), e0_str, FONT_MED);
BTX( BTN_POS(6,1), BTN_SIZE(3,1), e1_str, FONT_MED);
BTX( BTN_POS(2,2), BTN_SIZE(3,1), bed_str, FONT_MED);
BTX( BTN_POS(6,2), BTN_SIZE(3,1), fan_str, FONT_MED);
}
void StatusScreen::static_progress() {
CLCD::CommandFifo cmd;
#if defined(LCD_PORTRAIT)
THEME(progress) BTN( BTN_POS(1,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
THEME(progress) BTN( BTN_POS(5,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
#else
THEME(progress) BTN( BTN_POS(9,1), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
THEME(progress) BTN( BTN_POS(9,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
#endif
}
void StatusScreen::dynamic_progress() {
CLCD::CommandFifo cmd;
const uint32_t elapsed = Marlin_LCD_API::getProgress_seconds_elapsed();
const uint8_t hrs = elapsed/3600;
const uint8_t min = (elapsed/60)%60;
char time_str[10];
char progress_str[10];
sprintf_P(time_str, PSTR(" %02d : %02d"), hrs, min);
sprintf_P(progress_str, PSTR("%-3d %%"), Marlin_LCD_API::getProgress_percent() );
#if defined(LCD_PORTRAIT)
BTN_TAG(0)
BTX( BTN_POS(1,3), BTN_SIZE(4,1), time_str, FONT_MED);
BTX( BTN_POS(5,3), BTN_SIZE(4,1), progress_str, FONT_MED);
#else
BTN_TAG(0)
BTX( BTN_POS(9,1), BTN_SIZE(4,1), time_str, FONT_MED);
BTX( BTN_POS(9,2), BTN_SIZE(4,1), progress_str, FONT_MED);
#endif
}
#define GRID_COLS 4
void StatusScreen::static_interaction_buttons() {
CLCD::CommandFifo cmd;
#if defined(LCD_PORTRAIT)
BTN_TAG(1) THEME(stop_btn) BTN( BTN_POS(1,8), BTN_SIZE(4,1), F("STOP"), MENU_BTN_STYLE);
BTN_TAG(3) THEME(navi_btn) BTN( BTN_POS(1,9), BTN_SIZE(2,1), F(""), MENU_BTN_STYLE);
BTN_TAG(4) THEME(navi_btn) BTN( BTN_POS(3,9), BTN_SIZE(2,1), F("MENU"), MENU_BTN_STYLE);
#else
BTN_TAG(1) THEME(stop_btn) BTN( BTN_POS(1,7), BTN_SIZE(2,2), F("STOP"), MENU_BTN_STYLE);
BTN_TAG(3) THEME(navi_btn) BTN( BTN_POS(3,7), BTN_SIZE(1,2), F(""), MENU_BTN_STYLE);
BTN_TAG(4) THEME(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
}
#define GRID_COLS 1
void StatusScreen::dynamic_status_message() {
CLCD::CommandFifo cmd;
#if defined(LCD_PORTRAIT)
THEME(status_msg) BTN( BTN_POS(1,4), BTN_SIZE(1,1), lcd_status_message, FONT_LRG, OPT_FLAT);
#else
THEME(status_msg) BTN( BTN_POS(1,3), BTN_SIZE(1,2), lcd_status_message, FONT_LRG, OPT_FLAT);
#endif
}
#if defined(LCD_PORTRAIT)
#define GRID_COLS 8
#else
#define GRID_COLS 12
#endif
void StatusScreen::onStartup() {
// Load the bitmaps for the status screen
CLCD::Flash_Write_RGB332_Bitmap(TD_Icon_Info.RAMG_addr, TD_Icon, sizeof(TD_Icon));
CLCD::Flash_Write_RGB332_Bitmap(Extruder_Icon_Info.RAMG_addr, Extruder_Icon, sizeof(Extruder_Icon));
CLCD::Flash_Write_RGB332_Bitmap(Bed_Heat_Icon_Info.RAMG_addr, Bed_Heat_Icon, sizeof(Bed_Heat_Icon));
CLCD::Flash_Write_RGB332_Bitmap(Fan_Icon_Info.RAMG_addr, Fan_Icon, sizeof(Fan_Icon));
}
void StatusScreen::onRefresh() {
static CLCD::DLCache dlcache;
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
if(dlcache.hasData()) {
dlcache.append();
} else {
cmd.Cmd_Clear_Color(Theme::background);
cmd.Cmd_Clear(1,1,1);
static_temperature();
static_progress();
static_axis_position();
static_interaction_buttons();
dlcache.store();
}
/* Dynamic content, non-cached data follows */
dynamic_temperature();
dynamic_progress();
dynamic_status_message();
dynamic_axis_position();
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 *******************************/
#if defined(LCD_PORTRAIT)
#define GRID_ROWS 7
#define GRID_COLS 2
#else
#define GRID_ROWS 4
#define GRID_COLS 2
#endif
void MenuScreen::onRefresh() {
static CLCD::DLCache dlcache;
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
if(dlcache.hasData()) {
dlcache.append();
} else {
cmd.Cmd_Clear_Color(Theme::background);
cmd.Cmd_Clear(1,1,1);
#if defined(LCD_PORTRAIT)
BTN_TAG(2) THEME(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home"), MENU_BTN_STYLE);
BTN_TAG(3) THEME(menu_btn) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Move Axis"), MENU_BTN_STYLE);
BTN_TAG(4) THEME(menu_btn) BTN( BTN_POS(1,2), BTN_SIZE(2,1), F("Disable Steppers"), MENU_BTN_STYLE);
BTN_TAG(5) THEME(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(2,1), F("Temperature"), MENU_BTN_STYLE);
BTN_TAG(6) THEME(menu_btn) BTN( BTN_POS(1,4), BTN_SIZE(2,1), F("Advanced Settings"), MENU_BTN_STYLE);
BTN_TAG(8) THEME(menu_btn) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F("Recalibrate Screen"), MENU_BTN_STYLE);
BTN_TAG(7) THEME(menu_btn) BTN( BTN_POS(1,6), BTN_SIZE(2,1), F("About Firmware"), MENU_BTN_STYLE);
#else
BTN_TAG(2) THEME(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home"), MENU_BTN_STYLE);
BTN_TAG(3) THEME(menu_btn) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Move Axis"), MENU_BTN_STYLE);
BTN_TAG(4) THEME(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Disable Steppers"), MENU_BTN_STYLE);
BTN_TAG(5) THEME(menu_btn) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Temperature"), MENU_BTN_STYLE);
BTN_TAG(6) THEME(menu_btn) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Configuration"), MENU_BTN_STYLE);
BTN_TAG(7) THEME(menu_btn) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("About Firmware"), MENU_BTN_STYLE);
#endif
#define MARGIN_T 15
#if defined(LCD_PORTRAIT)
BTN_TAG(1) THEME(navi_btn) BTN( BTN_POS(1,7), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
#else
BTN_TAG(1) THEME(navi_btn) BTN( BTN_POS(1,4), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
#endif
#define MARGIN_T 5
dlcache.store();
}
cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP);
cmd.Cmd_Execute();
}
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 ****************************/
#if defined(LCD_PORTRAIT)
#define GRID_ROWS 6
#define GRID_COLS 2
#else
#define GRID_ROWS 4
#define GRID_COLS 2
#endif
void AdvancedSettingsScreen::onRefresh() {
static CLCD::DLCache dlcache;
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
if(dlcache.hasData()) {
dlcache.append();
} else {
cmd.Cmd_Clear_Color(Theme::background);
cmd.Cmd_Clear(1,1,1);
#if defined(LCD_PORTRAIT)
BTN_TAG(3) THEME(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,2), F("Z Offset "), MENU_BTN_STYLE);
BTN_TAG(4) THEME(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(1,2), F("Steps/mm"), MENU_BTN_STYLE);
BTN_TAG(6) THEME(disabled) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Velocity "), MENU_BTN_STYLE);
BTN_TAG(7) THEME(disabled) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Acceleration"), MENU_BTN_STYLE);
BTN_TAG(8) THEME(disabled) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("Jerk"), MENU_BTN_STYLE);
BTN_TAG(5) THEME(menu_btn) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F("Restore Failsafe"), MENU_BTN_STYLE);
BTN_TAG(1) THEME(navi_btn) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F("Save"), MENU_BTN_STYLE);
BTN_TAG(2) THEME(navi_btn) BTN( BTN_POS(2,6), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
#else
BTN_TAG(3) THEME(menu_btn) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Z Offset "), MENU_BTN_STYLE);
BTN_TAG(4) THEME(menu_btn) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Steps/mm"), MENU_BTN_STYLE);
BTN_TAG(6) THEME(disabled) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Velocity "), MENU_BTN_STYLE);
BTN_TAG(7) THEME(disabled) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Acceleration"), MENU_BTN_STYLE);
BTN_TAG(8) THEME(disabled) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("Jerk"), MENU_BTN_STYLE);
BTN_TAG(5) THEME(menu_btn) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Restore Failsafe"), MENU_BTN_STYLE);
BTN_TAG(1) THEME(navi_btn) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("Save"), MENU_BTN_STYLE);
BTN_TAG(2) THEME(navi_btn) BTN( BTN_POS(2,4), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
#endif
dlcache.store();
}
cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP);
cmd.Cmd_Execute();
}
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 ****************************/
#define GRID_COLS 4
#define GRID_ROWS 16
void CalibrationScreen::onRefresh() {
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
cmd.Cmd_Clear_Color(Theme::background);
cmd.Cmd_Clear(1,1,1);
#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
#if defined(LCD_800x480)
BTX( BTN_POS(1,1), BTN_SIZE(4,16), F("Touch the dots to calibrate"), FONT_LRG);
#else
BTX( BTN_POS(1,1), BTN_SIZE(4,16), F("Touch the dots to calibrate"), FONT_MED);
#endif
#endif
cmd.Cmd(CMD_CALIBRATE);
cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP);
cmd.Cmd_Execute();
}
void CalibrationScreen::onIdle() {
if(CLCD::CommandFifo::Cmd_Is_Idle()) {
GOTO_SCREEN(StatusScreen);
}
}
/***************************** CALIBRATION REGISTERS SCREEN ****************************/
#define MARGIN_T 5
#define GRID_ROWS 7
#define GRID_COLS 2
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(CMD_DLSTART);
cmd.Cmd_Clear_Color(Theme::background);
cmd.Cmd_Clear(1,1,1);
BTN_TAG(0)
THEME(transformA) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("TOUCH TRANSFORM_A"), 28, OPT_3D);
THEME(transformB) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("TOUCH TRANSFORM_B"), 28, OPT_3D);
THEME(transformC) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("TOUCH TRANSFORM_C"), 28, OPT_3D);
THEME(transformD) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("TOUCH TRANSFORM_D"), 28, OPT_3D);
THEME(transformE) BTN( BTN_POS(1,5), BTN_SIZE(1,1), F("TOUCH TRANSFORM_E"), 28, OPT_3D);
THEME(transformF) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F("TOUCH TRANSFORM_F"), 28, OPT_3D);
THEME(transformVal) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
THEME(transformVal) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
THEME(transformVal) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
THEME(transformVal) BTN( BTN_POS(2,4), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
THEME(transformVal) BTN( BTN_POS(2,5), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
THEME(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) THEME(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 ******************************/
#if defined(LCD_PORTRAIT)
#define GRID_COLS 6
#define GRID_ROWS 10
#else
#define GRID_COLS 9
#define GRID_ROWS 6
#endif
void ValueAdjusters::draw_increment_btn(const uint8_t tag, uint8_t decimals) {
CLCD::CommandFifo cmd;
const char *label = PSTR("?");
uint8_t pos;
switch(tag) {
case 20: label = PSTR( ".001"); pos = decimals - 3; break;
case 21: label = PSTR( ".01"); pos = decimals - 2; break;
case 22: label = PSTR( "0.1"); pos = decimals - 1; break;
case 23: label = PSTR( "1" ); pos = decimals + 0; break;
case 24: label = PSTR( "10" ); pos = decimals + 1; break;
case 25: label = PSTR("100" ); pos = decimals + 2; break;
default:
#if defined(UI_FRAMEWORK_DEBUG)
#if defined(SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLLNPAIR("Unknown tag for increment btn: ", tag);
#else
Serial.print(F("Unknown tag for increment btn:"));
Serial.println(tag);
#endif
#endif
}
BTN_TAG(tag)
switch(pos) {
#if defined(LCD_PORTRAIT)
case 0: BTN( BTN_POS(3,8), BTN_SIZE(1,1), progmem_str(label), FONT_SML, OPT_3D); break;
case 1: BTN( BTN_POS(4,8), BTN_SIZE(1,1), progmem_str(label), FONT_SML, OPT_3D); break;
case 2: BTN( BTN_POS(5,8), BTN_SIZE(1,1), progmem_str(label), FONT_SML, OPT_3D); break;
#else
case 0: BTN( BTN_POS(8,2), BTN_SIZE(2,1), progmem_str(label), FONT_MED, OPT_3D); break;
case 1: BTN( BTN_POS(8,3), BTN_SIZE(2,1), progmem_str(label), FONT_MED, OPT_3D); break;
case 2: BTN( BTN_POS(8,4), BTN_SIZE(2,1), progmem_str(label), FONT_MED, OPT_3D); break;
#endif
}
}
void ValueAdjusters::heading_t::static_parts() const {
CLCD::CommandFifo cmd;
cmd.Cmd_Clear_Color(Theme::adjust_bg);
cmd.Cmd_Clear(1,1,1);
// Draw all the buttons in the off state.
THEME(toggle_off);
draw_increment_btn(23 - decimals, decimals);
draw_increment_btn(24 - decimals, decimals);
draw_increment_btn(25 - decimals, decimals);
#if defined(LCD_PORTRAIT)
BTN_TAG(0) THEME(adjust_bg) BTN( BTN_POS(1,1), BTN_SIZE(6,1), (progmem_str) label, FONT_MED, OPT_FLAT);
BTN_TAG(0) THEME(adjust_bg) BTN( BTN_POS(1,7), BTN_SIZE(6,1), F("Increment:"), FONT_MED, OPT_FLAT);
BTN_TAG(1) THEME(navi_btn) BTN( BTN_POS(1,10), BTN_SIZE(6,1), F("Back"), MENU_BTN_STYLE);
#else
BTN_TAG(0) THEME(adjust_bg) BTN( BTN_POS(3,1), BTN_SIZE(4,1), (progmem_str) label, FONT_MED, OPT_FLAT);
BTN_TAG(0) THEME(adjust_bg) BTN( BTN_POS(8,1), BTN_SIZE(2,1), F("Increment"), FONT_MED, OPT_FLAT);
BTN_TAG(1) THEME(navi_btn) BTN( BTN_POS(8,6), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
#endif
}
void ValueAdjusters::heading_t::dynamic_parts() const {
CLCD::CommandFifo cmd;
THEME(toggle_on);
draw_increment_btn(increment, decimals);
}
#if defined(LCD_PORTRAIT)
#if defined(LCD_800x480)
#define EDGE_R 20
#else
#define EDGE_R 10
#endif
#else
#if defined(LCD_800x480)
#define EDGE_R 40
#else
#define EDGE_R 20
#endif
#endif
void ValueAdjusters::adjuster_t::static_parts() const {
CLCD::CommandFifo cmd;
progmem_str str = (progmem_str) label;
const uint8_t tag = line * 2;
BTN_TAG( 0 ) RGB(color) BTN( BTN_POS(3,line+1), BTN_SIZE(2,1), F(""), FONT_SML, OPT_FLAT);
BTN_TAG( 0 ) THEME(adjust_bg) BTN( BTN_POS(1,line+1), BTN_SIZE(2,1), str, FONT_SML, OPT_FLAT);
BTN_TAG(tag ) THEME(incr_btn) BTN( BTN_POS(5,line+1), BTN_SIZE(1,1), F("-"), FONT_MED, OPT_3D);
BTN_TAG(tag + 1) THEME(incr_btn) BTN( BTN_POS(6,line+1), BTN_SIZE(1,1), F("+"), FONT_MED, OPT_3D);
increment = 23 - decimals;
}
void ValueAdjusters::adjuster_t::dynamic_parts(float value) const {
CLCD::CommandFifo cmd;
char b[32];
dtostrf(value, 5, decimals, b);
strcat_P(b, PSTR(" "));
strcat_P(b, (const char*) units);
BTN_TAG(0)
BTX( BTN_POS(3,line+1), BTN_SIZE(2,1), b, FONT_SML);
}
void ValueAdjusters::onTouchStart(uint8_t tag) {
switch(tag) {
case 1: GOTO_PREVIOUS(); return;
case 2 ... 9: current_screen.onTouchHeld(tag); return;
case 20 ... 25: increment = tag; break;
}
current_screen.onRefresh();
}
float ValueAdjusters::getIncrement() {
switch(increment) {
case 20: return 0.001;
case 21: return 0.01;
case 22: return 0.1;
case 23: return 1.0;
case 24: return 10.0;
case 25: return 100.0;
}
}
uint8_t ValueAdjusters::increment = 20;
#define EDGE_R 0
/******************************** MOVE AXIS SCREEN ******************************/
void MoveAxisScreen::onRefresh() {
static CLCD::DLCache dlcache;
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
/* # Label: Units: Color: Precision: */
const heading_t a = { PSTR("Move Axis"), 1 };
const adjuster_t b = {1, PSTR("X:"), PSTR("mm"), Theme::x_axis, 1 };
const adjuster_t c = {2, PSTR("Y:"), PSTR("mm"), Theme::y_axis, 1 };
const adjuster_t d = {3, PSTR("Z:"), PSTR("mm"), Theme::z_axis, 1 };
if(dlcache.hasData()) {
dlcache.append();
} else {
a.static_parts();
b.static_parts();
c.static_parts();
d.static_parts();
dlcache.store();
}
a.dynamic_parts();
b.dynamic_parts(marlin_x_axis);
c.dynamic_parts(marlin_y_axis);
d.dynamic_parts(marlin_z_axis);
cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP);
cmd.Cmd_Execute();
}
void MoveAxisScreen::onTouchHeld(uint8_t tag) {
switch(tag) {
case 2: marlin_x_axis -= getIncrement(); break;
case 3: marlin_x_axis += getIncrement(); break;
case 4: marlin_y_axis -= getIncrement(); break;
case 5: marlin_y_axis += getIncrement(); break;
case 6: marlin_z_axis -= getIncrement(); break;
case 7: marlin_z_axis += getIncrement(); break;
}
onRefresh();
}
/******************************* TEMPERATURE SCREEN ******************************/
void TemperatureScreen::onRefresh() {
static CLCD::DLCache dlcache;
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
/* # Label: Units: Color: Precision: */
const heading_t a = { PSTR("Nozzle:"), 0 };
const adjuster_t b = {1, PSTR("Nozzle:"), PSTR("C"), Theme::temp, 0 };
const adjuster_t c = {2, PSTR("Bed:"), PSTR("C"), Theme::temp, 0 };
const adjuster_t d = {3, PSTR("Fan Speed:"), PSTR("%"), Theme::fan_speed, 0 };
if(dlcache.hasData()) {
dlcache.append();
} else {
a.static_parts();
b.static_parts();
c.static_parts();
d.static_parts();
dlcache.store();
}
a.dynamic_parts();
b.dynamic_parts(marlin_e0_temp);
c.dynamic_parts(marlin_bed_temp);
d.dynamic_parts(marlin_fan_speed);
cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP);
cmd.Cmd_Execute();
}
void TemperatureScreen::onTouchHeld(uint8_t tag) {
switch(tag) {
case 2: marlin_e0_temp -= getIncrement(); break;
case 3: marlin_e0_temp += getIncrement(); break;
case 4: marlin_bed_temp -= getIncrement(); break;
case 5: marlin_bed_temp += getIncrement(); break;
case 6: marlin_fan_speed -= getIncrement(); break;
case 7: marlin_fan_speed += getIncrement(); break;
}
onRefresh();
}
/******************************* STEPS SCREEN ******************************/
void StepsScreen::onRefresh() {
static CLCD::DLCache dlcache;
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
/* # Label: Units: Color: Precision: */
const heading_t a = { PSTR("Steps/mm"), 0};
const adjuster_t b = {1, PSTR("X:"), PSTR(""), Theme::x_axis, 0};
const adjuster_t c = {2, PSTR("Y:"), PSTR(""), Theme::y_axis, 0};
const adjuster_t d = {3, PSTR("Z:"), PSTR(""), Theme::z_axis, 0};
const adjuster_t e = {4, PSTR("E:"), PSTR(""), Theme::e_axis, 0};
if(dlcache.hasData()) {
dlcache.append();
} else {
a.static_parts();
b.static_parts();
c.static_parts();
d.static_parts();
e.static_parts();
dlcache.store();
}
a.dynamic_parts();
b.dynamic_parts(marlin_x_steps );
c.dynamic_parts(marlin_y_steps );
d.dynamic_parts(marlin_z_steps );
e.dynamic_parts(marlin_e0_steps);
cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP);
cmd.Cmd_Execute();
}
void StepsScreen::onTouchHeld(uint8_t tag) {
switch(tag) {
case 2: marlin_x_steps -= getIncrement(); break;
case 3: marlin_x_steps += getIncrement(); break;
case 4: marlin_y_steps -= getIncrement(); break;
case 5: marlin_y_steps += getIncrement(); break;
case 6: marlin_z_steps -= getIncrement(); break;
case 7: marlin_z_steps += getIncrement(); break;
case 8: marlin_e0_steps -= getIncrement(); break;
case 9: marlin_e0_steps += getIncrement(); break;
}
onRefresh();
}
/***************************** Z-OFFSET SCREEN ***************************/
void ZOffsetScreen::onRefresh() {
static CLCD::DLCache dlcache;
CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART);
/* # Label: Units: Color: Precision: */
const heading_t a = { PSTR("Z Offset"), 3 };
const adjuster_t b = {2, PSTR("Z Offset:"), PSTR("mm"), Theme::z_axis, 3 };
if(dlcache.hasData()) {
dlcache.append();
} else {
a.static_parts();
b.static_parts();
dlcache.store();
}
a.dynamic_parts();
b.dynamic_parts(marlin_z_offset);
cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP);
cmd.Cmd_Execute();
}
void ZOffsetScreen::onTouchHeld(uint8_t tag) {
switch(tag) {
case 4: marlin_z_offset -= getIncrement(); break;
case 5: marlin_z_offset += getIncrement(); 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::Cmd_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;
sound.play(Theme::unpress_sound);
}
else if(pressed != NONE) {
sound.play(Theme::unpress_sound);
current_screen.onTouchEnd(pressed);
pressed = NONE;
#if defined(UI_FRAMEWORK_DEBUG)
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLLNPAIR("Touch end: ", tag);
#else
Serial.print("Touch end: ");
Serial.println(tag);
#endif
#endif
}
}
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();
sound.play(Theme::press_sound);
#if defined(UI_FRAMEWORK_DEBUG)
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLLNPAIR("Touch start: ", tag);
#else
Serial.print("Touch start: ");
Serial.println(tag);
#endif
#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);
sound.play(Theme::repeat_sound);
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();}

@ -0,0 +1,180 @@
/****************************************************************************
* 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: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/********************** 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<method##_func_t*>(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 four values, allowing a menu of up to four levels.
class ScreenStack : public ScreenRef {
private:
uint8_t stack[4];
public:
void start() {
initializeAll();
onEntry();
}
void push() {
stack[3] = stack[2];
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] = stack[3];
stack[3] = 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();

@ -0,0 +1,112 @@
/****************************************************************************
* 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: <http://www.gnu.org/licenses/>. *
****************************************************************************/
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);
static const progmem_str getFirmwareName();
};
#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) {
return thermalManager.degHotend(extruder-1);
} else {
return thermalManager.degBed();
}
}
const float Marlin_LCD_API::getTargetTemp_celsius(const uint8_t extruder) {
if(extruder) {
return thermalManager.degTargetHotend(extruder-1);
} else {
return 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;
}
}
const Marlin_LCD_API::progmem_str Marlin_LCD_API::getFirmwareName() {
return F("Marlin " SHORT_BUILD_VERSION LULZBOT_FW_VERSION);
}
#endif

@ -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,27 @@
#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_USE_HIGH_RES
#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 +162,25 @@
#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_HIGH_RES
#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 +1917,21 @@
#define LULZBOT_LCD_CLEAR_DECL
#endif
#if defined(LULZBOT_USE_TOUCH_UI)
extern void lcd_update();
extern void lcd_buttons_update();
//#define LCD_IS_FT800
#define LCD_IS_FT810
#if defined(LULZBOT_USE_HIGH_RES)
#define LCD_800x480
#else
#define LCD_480x272
#endif
#define LCD_PORTRAIT
#define LCD_UPSIDE_DOWN
#define UI_FRAMEWORK_DEBUG
#endif
/***************************** CUSTOM SPLASH SCREEN *****************************/
#define LULZBOT_CUSTOM_BOOTSCREEN() \

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

@ -348,6 +348,17 @@
float coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
#endif
#if defined(LULZBOT_USE_TOUCH_UI)
#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;

@ -185,8 +185,9 @@
extern uint8_t progress_bar_percent;
#endif
#elif defined(LULZBOT_USE_TOUCH_UI)
// We will use our own definitions for these functions.
#else // no LCD
inline void lcd_update() {}
inline void lcd_init() {}
inline bool lcd_hasstatus() { return false; }
@ -198,7 +199,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))

Loading…
Cancel
Save