Add LULZBOT_TOUCH_UI (#14967)
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							179d6c4ed1
						
					
				
				
					commit
					274934ad81
				
			| @@ -2033,6 +2033,12 @@ | ||||
| // | ||||
| //#define MALYAN_LCD | ||||
|  | ||||
| // | ||||
| // LulzBot Color Touch UI for FTDI EVE (FT800/FT810) displays | ||||
| // See Configuration_adv.h for all configuration options. | ||||
| // | ||||
| //#defined LULZBOT_TOUCH_UI | ||||
|  | ||||
| // | ||||
| // Third-party or vendor-customized controller interfaces. | ||||
| // Sources should be installed in 'src/lcd/extensible_ui'. | ||||
|   | ||||
| @@ -1143,6 +1143,53 @@ | ||||
|  | ||||
| #endif // HAS_GRAPHICAL_LCD | ||||
|  | ||||
| // | ||||
| // Lulzbot Touch UI | ||||
| // | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|   // Display board used | ||||
|   //#define LCD_FTDI_VM800B35A        // FTDI 3.5" with FT800 (320x240) | ||||
|   //#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272) | ||||
|   //#define LCD_HAOYU_FT800CB         // Haoyu with 4.3" or 5" (480x272) | ||||
|   //#define LCD_HAOYU_FT810CB         // Haoyu with 5" (800x480) | ||||
|   //#define LCD_ALEPHOBJECTS_CLCD_UI  // Aleph Objects Color LCD UI | ||||
|  | ||||
|   // Correct the resolution if not using the stock TFT panel. | ||||
|   //#define TOUCH_UI_320x240 | ||||
|   //#define TOUCH_UI_480x272 | ||||
|   //#define TOUCH_UI_800x480 | ||||
|  | ||||
|   // Mappings for boards with a standard RepRapDiscount Display connector | ||||
|   //#define AO_EXP1_PINMAP    // AlephObjects CLCD UI EXP1 mapping | ||||
|   //#define AO_EXP2_PINMAP    // AlephObjects CLCD UI EXP2 mapping | ||||
|   //#define CR10_TFT_PINMAP   // Rudolph Riedel's CR10 pin mapping | ||||
|   //#define OTHER_PIN_LAYOUT  // Define pins manually below | ||||
|   #if ENABLED(OTHER_PIN_LAYOUT) | ||||
|     // The pins for CS and MOD_RESET (PD) must be chosen. | ||||
|     #define CLCD_MOD_RESET  9 | ||||
|     #define CLCD_SPI_CS    10 | ||||
|  | ||||
|     // If using software SPI, specify pins for SCLK, MOSI, MISO | ||||
|     //#define CLCD_USE_SOFT_SPI | ||||
|     #if ENABLED(CLCD_USE_SOFT_SPI) | ||||
|       #define CLCD_SOFT_SPI_MOSI 11 | ||||
|       #define CLCD_SOFT_SPI_MISO 12 | ||||
|       #define CLCD_SOFT_SPI_SCLK 13 | ||||
|     #endif | ||||
|   #endif | ||||
|  | ||||
|   // Display Orientation. An inverted (i.e. upside-down) display | ||||
|   // is supported on the FT800. The FT810 and beyond also support | ||||
|   // portrait and mirrored orientations. | ||||
|   //#define TOUCH_UI_INVERTED | ||||
|   //#define TOUCH_UI_PORTRAIT | ||||
|   //#define TOUCH_UI_MIRRORED | ||||
|  | ||||
|   // Use a numeric passcode for "Screen lock" keypad. | ||||
|   // (recommended for smaller displays) | ||||
|   //#define TOUCH_UI_PASSCODE | ||||
| #endif | ||||
|  | ||||
| // @section safety | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -70,7 +70,7 @@ | ||||
|   const uint32_t mask = MASK(DIO ## IO ## _PIN); \ | ||||
|   if (V) port->PIO_SODR = mask; \ | ||||
|   else port->PIO_CODR = mask; \ | ||||
| } while(0) | ||||
| }while(0) | ||||
|  | ||||
| // Toggle a pin | ||||
| #define _TOGGLE(IO) _WRITE(IO, !READ(IO)) | ||||
|   | ||||
| @@ -112,7 +112,7 @@ | ||||
|  * \def unused | ||||
|  * \brief Marking \a v as a unused parameter or value. | ||||
|  */ | ||||
| #define unused(v)          do { (void)(v); } while(0) | ||||
| #define unused(v)          do { (void)(v); }while(0) | ||||
|  | ||||
| /** | ||||
|  * \def barrier | ||||
| @@ -169,7 +169,7 @@ | ||||
|  * heuristics and inline the function no matter how big it thinks it | ||||
|  * becomes. | ||||
|  */ | ||||
| #if defined(__CC_ARM) | ||||
| #ifdef __CC_ARM | ||||
| #   define __always_inline   __forceinline | ||||
| #elif (defined __GNUC__) | ||||
| #ifdef __always_inline | ||||
| @@ -187,7 +187,7 @@ | ||||
|  * This annotation instructs the compiler to ignore its inlining | ||||
|  * heuristics and not inline the function. | ||||
|  */ | ||||
| #if defined(__CC_ARM) | ||||
| #ifdef __CC_ARM | ||||
| #   define __no_inline   __attribute__((noinline)) | ||||
| #elif (defined __GNUC__) | ||||
| #	define __no_inline   __attribute__((__noinline__)) | ||||
| @@ -204,7 +204,7 @@ | ||||
|  * | ||||
|  * \param expr  Expression to evaluate and supposed to be nonzero. | ||||
|  */ | ||||
| #if defined(_ASSERT_ENABLE_) | ||||
| #ifdef _ASSERT_ENABLE_ | ||||
| #  if defined(TEST_SUITE_DEFINE_ASSERT_MACRO) | ||||
|      // Assert() is defined in unit_test/suite.h | ||||
| #    include "unit_test/suite.h" | ||||
| @@ -998,14 +998,14 @@ typedef U8                  Byte;       //!< 8-bit unsigned integer. | ||||
| #endif  // #ifndef __ASSEMBLY__ | ||||
|  | ||||
|  | ||||
| #if defined(__ICCARM__) | ||||
| #ifdef __ICCARM__ | ||||
| #define SHORTENUM           __packed | ||||
| #elif defined(__GNUC__) | ||||
| #define SHORTENUM           __attribute__((packed)) | ||||
| #endif | ||||
|  | ||||
| /* No operation */ | ||||
| #if defined(__ICCARM__) | ||||
| #ifdef __ICCARM__ | ||||
| #define nop()               __no_operation() | ||||
| #elif defined(__GNUC__) | ||||
| #define nop()               (__NOP()) | ||||
|   | ||||
| @@ -142,10 +142,10 @@ public: | ||||
|   void print_bin(uint32_t value, uint8_t num_digits) { | ||||
|     uint32_t mask = 1 << (num_digits -1); | ||||
|     for (uint8_t i = 0; i < num_digits; i++) { | ||||
|       if (!(i % 4) && i)    write(' '); | ||||
|       if (!(i % 16)  && i)  write(' '); | ||||
|       if (value & mask)     write('1'); | ||||
|       else                  write('0'); | ||||
|       if (!(i %  4) && i) write(' '); | ||||
|       if (!(i % 16) && i) write(' '); | ||||
|       if (value & mask)   write('1'); | ||||
|       else                write('0'); | ||||
|       value <<= 1; | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -115,12 +115,12 @@ HAL_SERVO_TIMER_ISR() { | ||||
|       tc->COUNT16.CC[tcChannel].reg = (uint16_t)(tcCounterValue - 4UL);               // at least REFRESH_INTERVAL has elapsed | ||||
|   } | ||||
|   if (tcChannel == 0) { | ||||
|     SYNC(tc->COUNT16.SYNCBUSY.bit.CC0);  | ||||
|     SYNC(tc->COUNT16.SYNCBUSY.bit.CC0); | ||||
|     // Clear the interrupt | ||||
|     tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; | ||||
|   } | ||||
|   else { | ||||
|     SYNC(tc->COUNT16.SYNCBUSY.bit.CC1);  | ||||
|     SYNC(tc->COUNT16.SYNCBUSY.bit.CC1); | ||||
|     // Clear the interrupt | ||||
|     tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC1; | ||||
|   } | ||||
|   | ||||
| @@ -53,7 +53,7 @@ void FastIO_init(); // Must be called before using fast io macros | ||||
|   #define _WRITE(IO, V) do { \ | ||||
|     if (V) FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO])) ; \ | ||||
|     else   FastIOPortMap[STM_PORT(digitalPin[IO])]->BRR  = _BV32(STM_PIN(digitalPin[IO])) ; \ | ||||
|   } while(0) | ||||
|   }while(0) | ||||
| #else | ||||
|   #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO]) + (V ? 0 : 16))) | ||||
| #endif | ||||
|   | ||||
| @@ -38,8 +38,8 @@ | ||||
| #define _SET_OUTPUT(IO)       _SET_MODE(IO, GPIO_OUTPUT_PP) | ||||
| #define _SET_OUTPUT_OD(IO)    _SET_MODE(IO, GPIO_OUTPUT_OD) | ||||
|  | ||||
| #define OUT_WRITE(IO,V)       do{ _SET_OUTPUT(IO); WRITE(IO,V); } while(0) | ||||
| #define OUT_WRITE_OD(IO,V)    do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); } while(0) | ||||
| #define OUT_WRITE(IO,V)       do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) | ||||
| #define OUT_WRITE_OD(IO,V)    do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0) | ||||
|  | ||||
| #define SET_INPUT(IO)         _SET_MODE(IO, GPIO_INPUT_FLOATING) | ||||
| #define SET_INPUT_PULLUP(IO)  _SET_MODE(IO, GPIO_INPUT_PU) | ||||
|   | ||||
| @@ -118,24 +118,24 @@ | ||||
|   // Using GCC extensions, but Travis GCC version does not like it and gives | ||||
|   //  "error: statement-expressions are not allowed outside functions nor in template-argument lists" | ||||
|   #define NOLESS(v, n) \ | ||||
|     do { \ | ||||
|     do{ \ | ||||
|       __typeof__(n) _n = (n); \ | ||||
|       if (v < _n) v = _n; \ | ||||
|     } while(0) | ||||
|     }while(0) | ||||
|  | ||||
|   #define NOMORE(v, n) \ | ||||
|     do { \ | ||||
|     do{ \ | ||||
|       __typeof__(n) _n = (n); \ | ||||
|       if (v > _n) v = _n; \ | ||||
|     } while(0) | ||||
|     }while(0) | ||||
|  | ||||
|   #define LIMIT(v, n1, n2) \ | ||||
|     do { \ | ||||
|     do{ \ | ||||
|       __typeof__(n1) _n1 = (n1); \ | ||||
|       __typeof__(n2) _n2 = (n2); \ | ||||
|       if (v < _n1) v = _n1; \ | ||||
|       else if (v > _n2) v = _n2; \ | ||||
|     } while(0) | ||||
|     }while(0) | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -184,5 +184,5 @@ void print_bin(const uint16_t val); | ||||
|  | ||||
| void print_xyz(PGM_P const prefix, PGM_P const suffix, const float x, const float y, const float z); | ||||
| void print_xyz(PGM_P const prefix, PGM_P const suffix, const float xyz[]); | ||||
| #define SERIAL_POS(SUFFIX,VAR) do { print_xyz(PSTR("  " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); } while(0) | ||||
| #define SERIAL_XYZ(PREFIX,V...) do { print_xyz(PSTR(PREFIX), nullptr, V); } while(0) | ||||
| #define SERIAL_POS(SUFFIX,VAR) do { print_xyz(PSTR("  " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0) | ||||
| #define SERIAL_XYZ(PREFIX,V...) do { print_xyz(PSTR(PREFIX), nullptr, V); }while(0) | ||||
|   | ||||
| @@ -125,7 +125,7 @@ void LEDLights::set_color(const LEDColor &incol | ||||
|     // If the pins can do PWM then their intensity will be set. | ||||
|     #define UPDATE_RGBW(C,c) do { if (PWM_PIN(RGB_LED_##C##_PIN)) \ | ||||
|         analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \ | ||||
|       else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); } while(0) | ||||
|       else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); }while(0) | ||||
|     UPDATE_RGBW(R,r); | ||||
|     UPDATE_RGBW(G,g); | ||||
|     UPDATE_RGBW(B,b); | ||||
|   | ||||
| @@ -445,7 +445,7 @@ void GcodeSuite::G33() { | ||||
|              _tower_results       = (_4p_calibration && towers_set) || probe_points >= 3, | ||||
|              _opposite_results    = (_4p_calibration && !towers_set) || probe_points >= 3, | ||||
|              _endstop_results     = probe_points != 1 && probe_points != -1 && probe_points != 0, | ||||
|              _angle_results       = probe_points >= 3  && towers_set; | ||||
|              _angle_results       = probe_points >= 3 && towers_set; | ||||
|   static const char save_message[] PROGMEM = "Save with M500 and/or copy to Configuration.h"; | ||||
|   int8_t iterations = 0; | ||||
|   float test_precision, | ||||
|   | ||||
| @@ -284,7 +284,7 @@ void GcodeSuite::G34() { | ||||
|     // Home Z after the alignment procedure | ||||
|     process_subcommands_now_P(PSTR("G28 Z")); | ||||
|  | ||||
|   } while(0); | ||||
|   }while(0); | ||||
|  | ||||
|   if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< G34"); | ||||
| } | ||||
|   | ||||
| @@ -368,7 +368,7 @@ | ||||
| #endif | ||||
|  | ||||
| // Extensible UI serial touch screens. (See src/lcd/extensible_ui) | ||||
| #if EITHER(MALYAN_LCD, DGUS_LCD) | ||||
| #if ANY(MALYAN_LCD, DGUS_LCD, LULZBOT_TOUCH_UI) | ||||
|   #define IS_EXTUI | ||||
|   #define EXTENSIBLE_UI | ||||
| #endif | ||||
|   | ||||
| @@ -99,3 +99,6 @@ | ||||
|     #define LED_USER_PRESET_BRIGHTNESS 255 | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| // Extensible UI pin mapping for RepRapDiscount | ||||
| #define TOUCH_UI_ULTIPANEL ENABLED(LULZBOT_TOUCH_UI) && ANY(AO_EXP1_PINMAP, AO_EXP2_PINMAP, CR10_TFT_PINMAP) | ||||
|   | ||||
| @@ -1892,6 +1892,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | ||||
|   + ENABLED(OVERLORD_OLED) \ | ||||
|   + ENABLED(DGUS_LCD) \ | ||||
|   + ENABLED(MALYAN_LCD) \ | ||||
|   + ENABLED(LULZBOT_TOUCH_UI) \ | ||||
|   + ENABLED(FSMC_GRAPHICAL_TFT) | ||||
|   #error "Please select no more than one LCD controller option." | ||||
| #endif | ||||
|   | ||||
| @@ -0,0 +1,560 @@ | ||||
| /********************* | ||||
|  * flash_storage.cpp * | ||||
|  *********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../compat.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "../ftdi_eve_lib/ftdi_eve_lib.h" | ||||
|  | ||||
| #include "media_file_reader.h" | ||||
| #include "flash_storage.h" | ||||
|  | ||||
| // The following must be changed whenever the layout of the flash | ||||
| // data is changed in a manner that would render the data invalid. | ||||
|  | ||||
| constexpr uint32_t flash_eeprom_version = 1; | ||||
|  | ||||
| /* SPI Flash Memory Map: | ||||
|  * | ||||
|  * The following offsets and sizes are specified in 4k erase units: | ||||
|  * | ||||
|  * Page    Size     Description | ||||
|  * 0       16       DATA STORAGE AREA | ||||
|  * 16      1        VERSIONING DATA | ||||
|  * 17      inf      MEDIA STORAGE AREA | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #define DATA_STORAGE_SIZE_64K | ||||
|  | ||||
| using namespace FTDI::SPI; | ||||
| using namespace FTDI::SPI::most_significant_byte_first; | ||||
|  | ||||
| bool UIFlashStorage::is_present = false; | ||||
|  | ||||
| #ifdef SPI_FLASH_SS | ||||
| /************************** SPI Flash Chip Interface **************************/ | ||||
|  | ||||
|   void SPIFlash::wait_while_busy() { | ||||
|     uint8_t status; | ||||
|     safe_delay(1); | ||||
|     do { | ||||
|      spi_flash_select(); | ||||
|      spi_write_8(READ_STATUS_1); | ||||
|      status = spi_read_8(); | ||||
|      spi_flash_deselect(); | ||||
|      safe_delay(1); | ||||
|     } while (status & 1); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::erase_sector_4k(uint32_t addr) { | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(WRITE_ENABLE); | ||||
|     spi_flash_deselect(); | ||||
|  | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(ERASE_4K); | ||||
|     spi_write_24(addr); | ||||
|     spi_flash_deselect(); | ||||
|  | ||||
|     wait_while_busy(); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::erase_sector_64k(uint32_t addr) { | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(WRITE_ENABLE); | ||||
|     spi_flash_deselect(); | ||||
|  | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(ERASE_64K); | ||||
|     spi_write_24(addr); | ||||
|     spi_flash_deselect(); | ||||
|  | ||||
|     wait_while_busy(); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::spi_write_begin(uint32_t addr) { | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(WRITE_ENABLE); | ||||
|     spi_flash_deselect(); | ||||
|  | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(PAGE_PROGRAM); | ||||
|     spi_write_24(addr); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::spi_write_end() { | ||||
|     spi_flash_deselect(); | ||||
|     wait_while_busy(); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::spi_read_begin(uint32_t addr) { | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(READ_DATA); | ||||
|     spi_write_24(addr); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::spi_read_end() { | ||||
|     spi_flash_deselect(); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::erase_chip() { | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(WRITE_ENABLE); | ||||
|     spi_flash_deselect(); | ||||
|  | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(ERASE_CHIP); | ||||
|     spi_flash_deselect(); | ||||
|     wait_while_busy(); | ||||
|   } | ||||
|  | ||||
|   void SPIFlash::read_jedec_id(uint8_t &manufacturer_id, uint8_t &device_type, uint8_t &capacity) { | ||||
|     spi_flash_select(); | ||||
|     spi_write_8(READ_JEDEC_ID); | ||||
|     manufacturer_id = spi_recv(); | ||||
|     device_type     = spi_recv(); | ||||
|     capacity        = spi_recv(); | ||||
|     spi_flash_deselect (); | ||||
|   } | ||||
|  | ||||
|   /* This function writes "size" bytes from "data" starting at addr, while properly | ||||
|    * taking into account the special case of writing across a 256 byte page boundary. | ||||
|    * Returns the addr directly after the write. | ||||
|    */ | ||||
|   uint32_t SPIFlash::write(uint32_t addr, const void *_data, size_t size) { | ||||
|     const uint8_t *data = (const uint8_t*) _data; | ||||
|     while (size) { | ||||
|       const uint32_t page_start = addr & 0xFFFF00ul; | ||||
|       const uint32_t page_end   = page_start + 256; | ||||
|       const uint32_t write_size = min(page_end - addr, size); | ||||
|       spi_write_begin(addr); | ||||
|       spi_write_bulk<ram_write>(data, write_size); | ||||
|       spi_write_end(); | ||||
|       addr += write_size; | ||||
|       size -= write_size; | ||||
|       data += write_size; | ||||
|     } | ||||
|     return addr; | ||||
|   } | ||||
|  | ||||
|   uint32_t SPIFlash::read(uint32_t addr, void *data, size_t size) { | ||||
|     spi_read_begin(addr); | ||||
|     spi_read_bulk(data, size); | ||||
|     spi_read_end(); | ||||
|     return addr + size; | ||||
|   } | ||||
|  | ||||
|   /********************************** UTILITY ROUTINES *********************************/ | ||||
|  | ||||
|   bool UIFlashStorage::check_known_device() { | ||||
|     uint8_t manufacturer_id, device_type, capacity; | ||||
|     read_jedec_id(manufacturer_id, device_type, capacity); | ||||
|  | ||||
|     const bool is_known = | ||||
|         ((manufacturer_id == 0xEF) && (device_type == 0x40) && (capacity == 0x15)) || // unknown | ||||
|         ((manufacturer_id == 0x01) && (device_type == 0x40) && (capacity == 0x15)) || // Cypress S25FL116K | ||||
|         ((manufacturer_id == 0xEF) && (device_type == 0x14) && (capacity == 0x15)) || // Winbond W25Q16JV | ||||
|         ((manufacturer_id == 0x1F) && (device_type == 0x86) && (capacity == 0x01)) ;  // Adesto AT255F161 | ||||
|  | ||||
|     if (!is_known) { | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Unable to locate supported SPI Flash Memory."); | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("  Manufacturer ID, got: ", manufacturer_id); | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("  Device Type    , got: ", device_type); | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("  Capacity       , got: ", capacity); | ||||
|     } | ||||
|  | ||||
|     return is_known; | ||||
|   } | ||||
|  | ||||
|   void UIFlashStorage::initialize() { | ||||
|     for(uint8_t i = 0; i < 10; i++) { | ||||
|       if (check_known_device()) { | ||||
|         is_present = true; | ||||
|         break; | ||||
|       } | ||||
|       safe_delay(1000); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /**************************** DATA STORAGE AREA (first 4K or 64k) ********************/ | ||||
|  | ||||
|   #ifdef DATA_STORAGE_SIZE_64K | ||||
|     constexpr uint32_t data_storage_area_size = 64 * 1024; // Large erase unit | ||||
|   #else | ||||
|     constexpr uint32_t data_storage_area_size =  4 * 1024; // Small erase unit | ||||
|   #endif | ||||
|  | ||||
|   /* In order to provide some degree of wear leveling, each data write to the | ||||
|    * SPI Flash chip is appended to data that was already written before, until | ||||
|    * the data storage area is completely filled. New data is written preceeded | ||||
|    * with a 32-bit delimiter 'LULZ', so that we can distinguish written and | ||||
|    * unwritten data: | ||||
|    * | ||||
|    *        'LULZ'         <--- 1st record delimiter | ||||
|    *        <data_byte> | ||||
|    *        <data_byte> | ||||
|    *        <data_byte> | ||||
|    *        'LULZ'         <--- 2nd record delimiter | ||||
|    *        <data_byte> | ||||
|    *        <data_byte> | ||||
|    *        <data_byte> | ||||
|    *           ... | ||||
|    *        'LULZ'         <--- Last record delimiter | ||||
|    *        <data_byte> | ||||
|    *        <data_byte> | ||||
|    *        <data_byte> | ||||
|    *        0xFF           <--- Start of free space | ||||
|    *        0xFF | ||||
|    *           ... | ||||
|    * | ||||
|    * This function walks down the data storage area, verifying that the | ||||
|    * delimiters are either 'LULZ' or 0xFFFFFFFF. In the case that an invalid | ||||
|    * delimiter is found, this function returns -1, indicating that the Flash | ||||
|    * data is invalid (this will happen if the block_size changed with respect | ||||
|    * to earlier firmware). Otherwise, it returns the offset of the last | ||||
|    * valid delimiter 'LULZ', indicating the most recently written data. | ||||
|    */ | ||||
|   int32_t UIFlashStorage::get_config_read_offset(uint32_t block_size) { | ||||
|     uint16_t stride = 4 + block_size; | ||||
|     int32_t read_offset = -1; | ||||
|  | ||||
|     for(uint32_t offset = 0; offset < (data_storage_area_size - stride); offset += stride) { | ||||
|       uint32_t delim; | ||||
|       spi_read_begin(offset); | ||||
|       spi_read_bulk (&delim, sizeof(delim)); | ||||
|       spi_read_end(); | ||||
|       switch (delim) { | ||||
|         case 0xFFFFFFFFul: return read_offset; | ||||
|         case delimiter:    read_offset = offset; break; | ||||
|         default: | ||||
|           SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("Invalid delimiter in Flash: ", delim); | ||||
|           return -1; | ||||
|       } | ||||
|     } | ||||
|     SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("No LULZ delimiter found."); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   /* This function returns the offset at which new data should be | ||||
|    * appended, or -1 if the Flash needs to be erased */ | ||||
|   int32_t UIFlashStorage::get_config_write_offset(uint32_t block_size) { | ||||
|     int32_t read_offset = get_config_read_offset(block_size); | ||||
|     if (read_offset == -1) return -1; // The SPI flash is invalid | ||||
|  | ||||
|     int32_t write_offset = read_offset + 4 + block_size; | ||||
|     if ((write_offset + 4 + block_size) > data_storage_area_size) { | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Not enough free space in Flash."); | ||||
|       return -1; // Not enough free space | ||||
|     } | ||||
|     return write_offset; | ||||
|   } | ||||
|  | ||||
|   bool UIFlashStorage::verify_config_data(const void *data, size_t size) { | ||||
|     if (!is_present) return false; | ||||
|  | ||||
|     int32_t read_addr = get_config_read_offset(size); | ||||
|     if (read_addr == -1) return false; | ||||
|  | ||||
|     uint32_t delim; | ||||
|     spi_read_begin(read_addr); | ||||
|     spi_read_bulk (&delim, sizeof(delim)); | ||||
|     bool ok = spi_verify_bulk(data,size); | ||||
|     spi_read_end(); | ||||
|     return ok && delim == delimiter; | ||||
|   } | ||||
|  | ||||
|   bool UIFlashStorage::read_config_data(void *data, size_t size) { | ||||
|     if (!is_present) return false; | ||||
|  | ||||
|     int32_t read_addr = get_config_read_offset(size); | ||||
|     if (read_addr == -1) return false; | ||||
|  | ||||
|     uint32_t delim; | ||||
|     spi_read_begin(read_addr); | ||||
|     spi_read_bulk (&delim, sizeof(delim)); | ||||
|     spi_read_bulk (data, size); | ||||
|     spi_read_end(); | ||||
|     return delim == delimiter; | ||||
|   } | ||||
|  | ||||
|   void UIFlashStorage::write_config_data(const void *data, size_t size) { | ||||
|     if (!is_present) { | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("SPI Flash chip not present. Not saving UI settings."); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     // Since Flash storage has a limited number of write cycles, | ||||
|     // make sure that the data is different before rewriting. | ||||
|  | ||||
|     if (verify_config_data(data, size)) { | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("UI settings already written, skipping write."); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     int16_t write_addr = get_config_write_offset(size); | ||||
|     if (write_addr == -1) { | ||||
|       SERIAL_ECHO_START(); | ||||
|       SERIAL_ECHOPGM("Erasing UI settings from SPI Flash... "); | ||||
|       #ifdef DATA_STORAGE_SIZE_64K | ||||
|         erase_sector_64k(0); | ||||
|       #else | ||||
|         erase_sector_4k(0); | ||||
|       #endif | ||||
|       write_addr = 0; | ||||
|       SERIAL_ECHOLNPGM("DONE"); | ||||
|     } | ||||
|  | ||||
|     SERIAL_ECHO_START(); | ||||
|     SERIAL_ECHOPAIR("Writing UI settings to SPI Flash (offset ", write_addr); | ||||
|     SERIAL_ECHOPGM(")..."); | ||||
|  | ||||
|     const uint32_t delim = delimiter; | ||||
|     write_addr = write(write_addr, &delim, sizeof(delim)); | ||||
|     write_addr = write(write_addr, data, size); | ||||
|  | ||||
|     SERIAL_ECHOLNPGM("DONE"); | ||||
|   } | ||||
|  | ||||
|   /************************** VERSIONING INFO AREA ************************/ | ||||
|  | ||||
|   /* The version info area follows the data storage area. If the version | ||||
|    * is incorrect, the data on the chip is invalid and format_flash should | ||||
|    * be called. | ||||
|    */ | ||||
|  | ||||
|   typedef struct { | ||||
|     uint32_t magic; | ||||
|     uint32_t version; | ||||
|   } flash_version_info; | ||||
|  | ||||
|   constexpr uint32_t version_info_addr = data_storage_area_size; | ||||
|   constexpr uint32_t version_info_size = 4 * 1024; // Small erase unit | ||||
|  | ||||
|   bool UIFlashStorage::is_valid() { | ||||
|     flash_version_info info; | ||||
|  | ||||
|     spi_read_begin(version_info_addr); | ||||
|     spi_read_bulk (&info, sizeof(flash_version_info)); | ||||
|     spi_read_end(); | ||||
|  | ||||
|     return info.magic == delimiter && info.version == flash_eeprom_version; | ||||
|   } | ||||
|  | ||||
|   void UIFlashStorage::write_version_info() { | ||||
|     flash_version_info info; | ||||
|  | ||||
|     info.magic   = delimiter; | ||||
|     info.version = flash_eeprom_version; | ||||
|  | ||||
|     spi_write_begin(version_info_addr); | ||||
|     spi_write_bulk<ram_write>(&info, sizeof(flash_version_info)); | ||||
|     spi_write_end(); | ||||
|   } | ||||
|  | ||||
|   /**************************** MEDIA STORAGE AREA *****************************/ | ||||
|  | ||||
|   /* The media storage area follows the versioning info area. It consists | ||||
|    * of a file index followed by the data for one or more media files. | ||||
|    * | ||||
|    * The file index consists of an array of 32-bit file sizes. If a file | ||||
|    * is not present, the file's size will be set to 0xFFFFFFFF | ||||
|    */ | ||||
|  | ||||
|   constexpr uint32_t media_storage_addr    = version_info_addr + version_info_size; | ||||
|   constexpr uint8_t  media_storage_slots   = 4; | ||||
|  | ||||
|   void UIFlashStorage::format_flash() { | ||||
|     SERIAL_ECHO_START(); SERIAL_ECHOPGM("Erasing SPI Flash..."); | ||||
|     SPIFlash::erase_chip(); | ||||
|     SERIAL_ECHOLNPGM("DONE"); | ||||
|  | ||||
|     write_version_info(); | ||||
|   } | ||||
|  | ||||
|   uint32_t UIFlashStorage::get_media_file_start(uint8_t slot) { | ||||
|     uint32_t addr = media_storage_addr + sizeof(uint32_t) * media_storage_slots; | ||||
|     spi_read_begin(media_storage_addr); | ||||
|     for(uint8_t i = 0; i < slot; i++) { | ||||
|       addr += spi_read_32(); | ||||
|     } | ||||
|     spi_read_end(); | ||||
|     return addr; | ||||
|   } | ||||
|  | ||||
|   void UIFlashStorage::set_media_file_size(uint8_t slot, uint32_t size) { | ||||
|     spi_write_begin(media_storage_addr + sizeof(uint32_t) * slot); | ||||
|     spi_write_32(size); | ||||
|     spi_write_end(); | ||||
|   } | ||||
|  | ||||
|   uint32_t UIFlashStorage::get_media_file_size(uint8_t slot) { | ||||
|     spi_read_begin(media_storage_addr + sizeof(uint32_t) * slot); | ||||
|     uint32_t size = spi_read_32(); | ||||
|     spi_read_end(); | ||||
|     return size; | ||||
|   } | ||||
|  | ||||
|   /* Writes a media file from the SD card/USB flash drive into a slot on the SPI Flash. Media | ||||
|    * files must be written sequentially following by a chip erase and it is not possible to | ||||
|    * overwrite files. */ | ||||
|   UIFlashStorage::error_t UIFlashStorage::write_media_file(progmem_str filename, uint8_t slot) { | ||||
|     #if ENABLED(SDSUPPORT) | ||||
|       uint32_t addr; | ||||
|       uint8_t buff[write_page_size]; | ||||
|  | ||||
|       strcpy_P( (char*) buff, (const char*) filename); | ||||
|  | ||||
|       MediaFileReader reader; | ||||
|       if (!reader.open((char*) buff)) { | ||||
|         SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Unable to find media file"); | ||||
|         return FILE_NOT_FOUND; | ||||
|       } | ||||
|  | ||||
|       if (get_media_file_size(slot) != 0xFFFFFFFFUL) { | ||||
|         SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Media file already exists"); | ||||
|         return WOULD_OVERWRITE; | ||||
|       } | ||||
|  | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOPGM("Writing SPI Flash..."); | ||||
|  | ||||
|       set_media_file_size(slot, reader.size()); | ||||
|       addr = get_media_file_start(slot); | ||||
|  | ||||
|       // Write out the file itself | ||||
|       for(;;) { | ||||
|         const int16_t nBytes = reader.read(buff, write_page_size); | ||||
|         if (nBytes == -1) { | ||||
|           SERIAL_ECHOLNPGM("Failed to read from file"); | ||||
|           return READ_ERROR; | ||||
|         } | ||||
|  | ||||
|         addr = write(addr, buff, nBytes); | ||||
|         if (nBytes != write_page_size) | ||||
|           break; | ||||
|  | ||||
|         #if ENABLED(EXTENSIBLE_UI) | ||||
|           ExtUI::yield(); | ||||
|         #endif | ||||
|       } | ||||
|  | ||||
|       SERIAL_ECHOLNPGM("DONE"); | ||||
|  | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOPGM("Verifying SPI Flash..."); | ||||
|  | ||||
|       bool verifyOk = true; | ||||
|  | ||||
|       // Verify the file index | ||||
|  | ||||
|       if (get_media_file_start(slot+1) != (get_media_file_start(slot) + reader.size())) { | ||||
|         SERIAL_ECHOLNPGM("File index verification failed. "); | ||||
|         verifyOk = false; | ||||
|       } | ||||
|  | ||||
|       // Verify the file itself | ||||
|       addr = get_media_file_start(slot); | ||||
|       reader.rewind(); | ||||
|  | ||||
|       while (verifyOk) { | ||||
|         const int16_t nBytes = reader.read(buff, write_page_size); | ||||
|         if (nBytes == -1) { | ||||
|           SERIAL_ECHOPGM("Failed to read from file"); | ||||
|           verifyOk = false; | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|         spi_read_begin(addr); | ||||
|         if (!spi_verify_bulk(buff, nBytes)) { | ||||
|           verifyOk = false; | ||||
|           spi_read_end(); | ||||
|           break; | ||||
|         } | ||||
|         spi_read_end(); | ||||
|  | ||||
|         addr += nBytes; | ||||
|         if (nBytes != write_page_size) break; | ||||
|         #if ENABLED(EXTENSIBLE_UI) | ||||
|           ExtUI::yield(); | ||||
|         #endif | ||||
|       }; | ||||
|  | ||||
|       if (verifyOk) { | ||||
|         SERIAL_ECHOLNPGM("DONE"); | ||||
|         return SUCCESS; | ||||
|       } else { | ||||
|         SERIAL_ECHOLNPGM("FAIL"); | ||||
|         return VERIFY_ERROR; | ||||
|       } | ||||
|     #else | ||||
|       return VERIFY_ERROR; | ||||
|     #endif // ENABLED(SDSUPPORT) | ||||
|   } | ||||
|  | ||||
|   bool UIFlashStorage::BootMediaReader::isAvailable(uint32_t slot) { | ||||
|     if (!is_present) return false; | ||||
|  | ||||
|     bytes_remaining = get_media_file_size(slot); | ||||
|     if (bytes_remaining != 0xFFFFFFFFUL) { | ||||
|       SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("Boot media file size:", bytes_remaining); | ||||
|       addr = get_media_file_start(slot); | ||||
|       return true; | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   int16_t UIFlashStorage::BootMediaReader::read(void *data, const size_t size) { | ||||
|     if (bytes_remaining == 0xFFFFFFFFUL) return -1; | ||||
|  | ||||
|     if (size > bytes_remaining) | ||||
|       return read(data, bytes_remaining); | ||||
|  | ||||
|     if (size > 0) { | ||||
|       spi_read_begin(addr); | ||||
|       spi_read_bulk(data, size); | ||||
|       spi_read_end(); | ||||
|       addr += size; | ||||
|       bytes_remaining -= size; | ||||
|     } | ||||
|  | ||||
|     return size; | ||||
|   } | ||||
|  | ||||
|   int16_t UIFlashStorage::BootMediaReader::read(void *obj, void *data, const size_t size) { | ||||
|     return reinterpret_cast<UIFlashStorage::BootMediaReader*>(obj)->read(data, size); | ||||
|   } | ||||
|  | ||||
| #else | ||||
|   void UIFlashStorage::initialize()                                           {} | ||||
|   bool UIFlashStorage::is_valid()                                             {return true;} | ||||
|   void UIFlashStorage::write_config_data(const void *, size_t)                {} | ||||
|   bool UIFlashStorage::verify_config_data(const void *, size_t)               {return false;} | ||||
|   bool UIFlashStorage::read_config_data(void *, size_t )                      {return false;} | ||||
|   UIFlashStorage::error_t UIFlashStorage::write_media_file(progmem_str, uint8_t) {return FILE_NOT_FOUND;} | ||||
|   void UIFlashStorage::format_flash()                                         {} | ||||
|  | ||||
|   bool UIFlashStorage::BootMediaReader::isAvailable(uint32_t)                 {return false;} | ||||
|   int16_t UIFlashStorage::BootMediaReader::read(void *, const size_t)         {return -1;} | ||||
|   int16_t UIFlashStorage::BootMediaReader::read(void *, void *, const size_t) {return -1;} | ||||
| #endif // SPI_FLASH_SS | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,110 @@ | ||||
| /******************* | ||||
|  * flash_storage.h * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #ifdef LULZBOT_TOUCH_UI | ||||
|  | ||||
| class SPIFlash { | ||||
|   public: | ||||
|     static constexpr uint32_t erase_unit_size = 4 * 1024; // Minimum erase unit | ||||
|     static constexpr uint32_t write_page_size = 256;      // Minimum page write unit | ||||
|  | ||||
|     enum { | ||||
|       READ_STATUS_1 = 0x05, | ||||
|       READ_STATUS_2 = 0x35, | ||||
|       READ_STATUS_3 = 0x33, | ||||
|       WRITE_ENABLE  = 0x06, | ||||
|       WRITE_DISABLE = 0x04, | ||||
|       READ_ID       = 0x90, | ||||
|       READ_JEDEC_ID = 0x9F, | ||||
|       READ_DATA     = 0x03, | ||||
|       PAGE_PROGRAM  = 0x02, | ||||
|       ERASE_4K      = 0x20, | ||||
|       ERASE_64K     = 0xD8, | ||||
|       ERASE_CHIP    = 0xC7 | ||||
|     }; | ||||
|  | ||||
|     static void wait_while_busy(); | ||||
|     static void erase_sector_4k(uint32_t addr); | ||||
|     static void erase_sector_64k(uint32_t addr); | ||||
|     static void erase_chip  (); | ||||
|  | ||||
|     static void read_jedec_id(uint8_t &manufacturer_id, uint8_t &device_type, uint8_t &capacity); | ||||
|  | ||||
|     static void spi_read_begin(uint32_t addr); | ||||
|     static void spi_read_end(); | ||||
|  | ||||
|     static void spi_write_begin(uint32_t addr); | ||||
|     static void spi_write_end(); | ||||
|  | ||||
|     static uint32_t write(uint32_t addr, const void *data, size_t size); | ||||
|     static uint32_t read(uint32_t addr, void *data, size_t size); | ||||
| }; | ||||
|  | ||||
| class UIFlashStorage : private SPIFlash { | ||||
|   private: | ||||
|  | ||||
|     static bool is_present; | ||||
|     static int32_t  get_config_read_offset(uint32_t block_size); | ||||
|     static int32_t  get_config_write_offset(uint32_t block_size); | ||||
|  | ||||
|     static uint32_t get_media_file_start(uint8_t slot); | ||||
|     static void     set_media_file_size(uint8_t slot, uint32_t size); | ||||
|     static uint32_t get_media_file_size(uint8_t slot); | ||||
|  | ||||
|     static constexpr uint32_t delimiter = 0x4C554C5A; // 'LULZ' | ||||
|   public: | ||||
|     enum error_t { | ||||
|       SUCCESS, | ||||
|       FILE_NOT_FOUND, | ||||
|       READ_ERROR, | ||||
|       VERIFY_ERROR, | ||||
|       WOULD_OVERWRITE | ||||
|     }; | ||||
|  | ||||
|     static void    initialize  (); | ||||
|     static void    format_flash (); | ||||
|     static bool    check_known_device(); | ||||
|  | ||||
|     static bool    is_valid (); | ||||
|     static void    write_version_info(); | ||||
|  | ||||
|     static void    write_config_data  (const void *data, size_t size); | ||||
|     static bool    verify_config_data (const void *data, size_t size); | ||||
|     static bool    read_config_data   (void *data, size_t size); | ||||
|     static error_t write_media_file   (progmem_str filename, uint8_t slot = 0); | ||||
|  | ||||
|     class BootMediaReader; | ||||
| }; | ||||
|  | ||||
| class UIFlashStorage::BootMediaReader { | ||||
|   private: | ||||
|     uint32_t addr; | ||||
|     uint32_t bytes_remaining; | ||||
|  | ||||
|   public: | ||||
|     bool isAvailable(uint32_t slot = 0); | ||||
|     int16_t read(void *buffer, size_t const size); | ||||
|  | ||||
|     static int16_t read(void *obj, void *buffer, const size_t size); | ||||
| }; | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,63 @@ | ||||
| /************************ | ||||
|  * media_filereader.cpp * | ||||
|  ************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../compat.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|   #include "media_file_reader.h" | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|     bool MediaFileReader::open(const char* filename) { | ||||
|       card.init(SPI_SPEED, SDSS); | ||||
|       volume.init(&card); | ||||
|       root.openRoot(&volume); | ||||
|       return file.open(&root, filename, O_READ); | ||||
|     } | ||||
|  | ||||
|     int16_t MediaFileReader::read(void *buff, size_t bytes) { | ||||
|       return file.read(buff, bytes); | ||||
|     } | ||||
|  | ||||
|     void MediaFileReader::close() { | ||||
|       file.close(); | ||||
|     } | ||||
|  | ||||
|     uint32_t MediaFileReader::size() { | ||||
|       return file.fileSize(); | ||||
|     } | ||||
|  | ||||
|     void MediaFileReader::rewind() { | ||||
|       file.rewind(); | ||||
|     } | ||||
|  | ||||
|     int16_t MediaFileReader::read(void *obj, void *buff, size_t bytes) { | ||||
|       return reinterpret_cast<MediaFileReader*>(obj)->read(buff, bytes); | ||||
|     } | ||||
|   #else | ||||
|     bool MediaFileReader::open(const char*)               {return -1;} | ||||
|     int16_t MediaFileReader::read(void *, size_t)         {return 0;} | ||||
|     void MediaFileReader::close()                         {} | ||||
|     uint32_t MediaFileReader::size()                      {return 0;} | ||||
|     void MediaFileReader::rewind()                        {} | ||||
|     int16_t MediaFileReader::read(void *, void *, size_t) {return 0;} | ||||
|   #endif | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,44 @@ | ||||
| /********************** | ||||
|  * media_filereader.h * | ||||
|  **********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../../../../../sd/SdFile.h" | ||||
| #include "../../../../../sd/cardreader.h" | ||||
|  | ||||
| class MediaFileReader { | ||||
|   private: | ||||
|     #if ENABLED(SDSUPPORT) | ||||
|       Sd2Card  card; | ||||
|       SdVolume volume; | ||||
|       SdFile   root, file; | ||||
|     #endif | ||||
|  | ||||
|   public: | ||||
|     bool open(const char* filename); | ||||
|     int16_t read(void *buff, size_t bytes); | ||||
|     uint32_t size(); | ||||
|     void rewind(); | ||||
|     void close(); | ||||
|  | ||||
|     static int16_t read(void *obj, void *buff, size_t bytes); | ||||
| }; | ||||
							
								
								
									
										61
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/compat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/compat.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| /************ | ||||
|  * compat.h * | ||||
|  ************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /** | ||||
|  * This following provides compatibility whether compiling | ||||
|  * as a part of Marlin or outside it | ||||
|  */ | ||||
|  | ||||
| #if defined __has_include | ||||
|   #if __has_include ("../../ui_api.h") | ||||
|     #include "../../ui_api.h" | ||||
|   #endif | ||||
| #else | ||||
|   #include "../../ui_api.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef __MARLIN_FIRMWARE__ | ||||
|     // If __MARLIN_FIRMWARE__ exists, then we are being | ||||
|     // compiled inside Marlin. | ||||
|     #include "pin_mappings.h" | ||||
| #else | ||||
|   // Messages that are declared in Marlin | ||||
|   #define WELCOME_MSG     "Printer Ready" | ||||
|   #define MSG_SD_INSERTED "Media Inserted" | ||||
|   #define MSG_SD_REMOVED  "Media Removed" | ||||
|  | ||||
|   // Define macros for compatibility | ||||
|   #define EXTENSIBLE_UI | ||||
|   #define _CAT(a, ...) a ## __VA_ARGS__ | ||||
|   #define SWITCH_ENABLED_      1 | ||||
|   #define ENABLED(b) _CAT(SWITCH_ENABLED_, b) | ||||
|   #define DISABLED(b) !ENABLED(b) | ||||
|  | ||||
|   namespace UI { | ||||
|     static inline uint32_t safe_millis() {return millis();}; | ||||
|     static inline void     yield()       {}; | ||||
|   }; | ||||
| #endif | ||||
|  | ||||
| class __FlashStringHelper; | ||||
| typedef const __FlashStringHelper *progmem_str; | ||||
							
								
								
									
										98
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /************ | ||||
|  * config.h * | ||||
|  ************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "compat.h" | ||||
|  | ||||
| // Define the display board used (see "ftdi_eve_boards.h" for definitions) | ||||
|  | ||||
| //#define LCD_FTDI_VM800B35A        // FTDI 3.5" 320x240 with FT800 | ||||
| //#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" 480x272 | ||||
| //#define LCD_HAOYU_FT800CB         // Haoyu with 4.3" or 5" 480x272 | ||||
| //#define LCD_HAOYU_FT810CB         // Haoyu with 5" 800x480 | ||||
| //#define LCD_ALEPHOBJECTS_CLCD_UI  // Aleph Objects Color LCD User Interface | ||||
|  | ||||
| // Leave the following commented out to use a board's default resolution. | ||||
| // If you have changed the LCD panel, you may override the resolution | ||||
| // below (see "ftdi_eve_resolutions.h" for definitions): | ||||
|  | ||||
| //#define TOUCH_UI_320x240 | ||||
| //#define TOUCH_UI_480x272 | ||||
| //#define TOUCH_UI_800x480 | ||||
|  | ||||
| // Define the printer interface or pins used (see "ui_pin_mappings.h" for definitions): | ||||
|  | ||||
| //#define CR10_TFT_PINMAP | ||||
| //#define AO_EXP1_DEPRECATED_PINMAP  // UltraLCD EXP1 connector, old AlephObject's wiring | ||||
| //#define AO_EXP1_PINMAP  // UltraLCD EXP1 connector, new AlephObject's wiring | ||||
| //#define AO_EXP2_PINMAP  // UltraLCD EXP2 connector, new AlephObject's wiring | ||||
| //#define OTHER_PIN_LAYOUT | ||||
|  | ||||
| // Otherwise. Define all the pins manually: | ||||
|  | ||||
| #ifdef OTHER_PIN_LAYOUT | ||||
|     // Select interfacing pins, the following pin specifiers are supported: | ||||
|     // | ||||
|     //     ARDUINO_DIGITAL_1  - Arduino pin via digitalWrite/digitalRead | ||||
|     //     AVR_A1             - Fast AVR port access via PORTA/PINA/DDRA | ||||
|     //     1                  - When compiling Marlin, use Marlin pin IDs. | ||||
|  | ||||
|     // The pins for CS and MOD_RESET (PD) must be chosen. | ||||
|     #define CLCD_MOD_RESET                      9 | ||||
|     #define CLCD_SPI_CS                        10 | ||||
|  | ||||
|     // If using software SPI, specify pins for SCLK, MOSI, MISO | ||||
|     //#define CLCD_USE_SOFT_SPI | ||||
|     #ifdef CLCD_USE_SOFT_SPI | ||||
|         #define CLCD_SOFT_SPI_MOSI             11 | ||||
|         #define CLCD_SOFT_SPI_MISO             12 | ||||
|         #define CLCD_SOFT_SPI_SCLK             13 | ||||
|     #endif | ||||
| #endif | ||||
|  | ||||
| // Defines how to orient the display. An inverted (i.e. upside-down) display | ||||
| // is supported on the FT800. The FT810 or better also support a portrait | ||||
| // and mirrored orientation. | ||||
| //#define TOUCH_UI_INVERTED | ||||
| //#define TOUCH_UI_PORTRAIT | ||||
| //#define TOUCH_UI_MIRRORED | ||||
|  | ||||
| // Use a numeric passcode for "Parental lock". | ||||
| // This is a recommended for smaller displays. | ||||
| //#define TOUCH_UI_PASSCODE | ||||
|  | ||||
| // Define number of seconds after which the menu screens | ||||
| // timeout and returns the user to the status screen | ||||
| //#define LCD_TIMEOUT_TO_STATUS 120 | ||||
|  | ||||
| // Enable this to debug the event framework | ||||
| //#define UI_FRAMEWORK_DEBUG | ||||
|  | ||||
| // Enable the developer's menu and screens | ||||
| //#define DEVELOPER_SCREENS | ||||
|  | ||||
| // Maximum feed rate for manual extrusion (mm/s) | ||||
| //#define MAX_MANUAL_FEEDRATE 240 | ||||
|  | ||||
| // Sets the SPI speed in Hz | ||||
|  | ||||
| #define SPI_FREQUENCY 8000000 >> SPI_SPEED | ||||
| @@ -0,0 +1,674 @@ | ||||
|                     GNU GENERAL PUBLIC LICENSE | ||||
|                        Version 3, 29 June 2007 | ||||
|  | ||||
|  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | ||||
|  Everyone is permitted to copy and distribute verbatim copies | ||||
|  of this license document, but changing it is not allowed. | ||||
|  | ||||
|                             Preamble | ||||
|  | ||||
|   The GNU General Public License is a free, copyleft license for | ||||
| software and other kinds of works. | ||||
|  | ||||
|   The licenses for most software and other practical works are designed | ||||
| to take away your freedom to share and change the works.  By contrast, | ||||
| the GNU General Public License is intended to guarantee your freedom to | ||||
| share and change all versions of a program--to make sure it remains free | ||||
| software for all its users.  We, the Free Software Foundation, use the | ||||
| GNU General Public License for most of our software; it applies also to | ||||
| any other work released this way by its authors.  You can apply it to | ||||
| your programs, too. | ||||
|  | ||||
|   When we speak of free software, we are referring to freedom, not | ||||
| price.  Our General Public Licenses are designed to make sure that you | ||||
| have the freedom to distribute copies of free software (and charge for | ||||
| them if you wish), that you receive source code or can get it if you | ||||
| want it, that you can change the software or use pieces of it in new | ||||
| free programs, and that you know you can do these things. | ||||
|  | ||||
|   To protect your rights, we need to prevent others from denying you | ||||
| these rights or asking you to surrender the rights.  Therefore, you have | ||||
| certain responsibilities if you distribute copies of the software, or if | ||||
| you modify it: responsibilities to respect the freedom of others. | ||||
|  | ||||
|   For example, if you distribute copies of such a program, whether | ||||
| gratis or for a fee, you must pass on to the recipients the same | ||||
| freedoms that you received.  You must make sure that they, too, receive | ||||
| or can get the source code.  And you must show them these terms so they | ||||
| know their rights. | ||||
|  | ||||
|   Developers that use the GNU GPL protect your rights with two steps: | ||||
| (1) assert copyright on the software, and (2) offer you this License | ||||
| giving you legal permission to copy, distribute and/or modify it. | ||||
|  | ||||
|   For the developers' and authors' protection, the GPL clearly explains | ||||
| that there is no warranty for this free software.  For both users' and | ||||
| authors' sake, the GPL requires that modified versions be marked as | ||||
| changed, so that their problems will not be attributed erroneously to | ||||
| authors of previous versions. | ||||
|  | ||||
|   Some devices are designed to deny users access to install or run | ||||
| modified versions of the software inside them, although the manufacturer | ||||
| can do so.  This is fundamentally incompatible with the aim of | ||||
| protecting users' freedom to change the software.  The systematic | ||||
| pattern of such abuse occurs in the area of products for individuals to | ||||
| use, which is precisely where it is most unacceptable.  Therefore, we | ||||
| have designed this version of the GPL to prohibit the practice for those | ||||
| products.  If such problems arise substantially in other domains, we | ||||
| stand ready to extend this provision to those domains in future versions | ||||
| of the GPL, as needed to protect the freedom of users. | ||||
|  | ||||
|   Finally, every program is threatened constantly by software patents. | ||||
| States should not allow patents to restrict development and use of | ||||
| software on general-purpose computers, but in those that do, we wish to | ||||
| avoid the special danger that patents applied to a free program could | ||||
| make it effectively proprietary.  To prevent this, the GPL assures that | ||||
| patents cannot be used to render the program non-free. | ||||
|  | ||||
|   The precise terms and conditions for copying, distribution and | ||||
| modification follow. | ||||
|  | ||||
|                        TERMS AND CONDITIONS | ||||
|  | ||||
|   0. Definitions. | ||||
|  | ||||
|   "This License" refers to version 3 of the GNU General Public License. | ||||
|  | ||||
|   "Copyright" also means copyright-like laws that apply to other kinds of | ||||
| works, such as semiconductor masks. | ||||
|  | ||||
|   "The Program" refers to any copyrightable work licensed under this | ||||
| License.  Each licensee is addressed as "you".  "Licensees" and | ||||
| "recipients" may be individuals or organizations. | ||||
|  | ||||
|   To "modify" a work means to copy from or adapt all or part of the work | ||||
| in a fashion requiring copyright permission, other than the making of an | ||||
| exact copy.  The resulting work is called a "modified version" of the | ||||
| earlier work or a work "based on" the earlier work. | ||||
|  | ||||
|   A "covered work" means either the unmodified Program or a work based | ||||
| on the Program. | ||||
|  | ||||
|   To "propagate" a work means to do anything with it that, without | ||||
| permission, would make you directly or secondarily liable for | ||||
| infringement under applicable copyright law, except executing it on a | ||||
| computer or modifying a private copy.  Propagation includes copying, | ||||
| distribution (with or without modification), making available to the | ||||
| public, and in some countries other activities as well. | ||||
|  | ||||
|   To "convey" a work means any kind of propagation that enables other | ||||
| parties to make or receive copies.  Mere interaction with a user through | ||||
| a computer network, with no transfer of a copy, is not conveying. | ||||
|  | ||||
|   An interactive user interface displays "Appropriate Legal Notices" | ||||
| to the extent that it includes a convenient and prominently visible | ||||
| feature that (1) displays an appropriate copyright notice, and (2) | ||||
| tells the user that there is no warranty for the work (except to the | ||||
| extent that warranties are provided), that licensees may convey the | ||||
| work under this License, and how to view a copy of this License.  If | ||||
| the interface presents a list of user commands or options, such as a | ||||
| menu, a prominent item in the list meets this criterion. | ||||
|  | ||||
|   1. Source Code. | ||||
|  | ||||
|   The "source code" for a work means the preferred form of the work | ||||
| for making modifications to it.  "Object code" means any non-source | ||||
| form of a work. | ||||
|  | ||||
|   A "Standard Interface" means an interface that either is an official | ||||
| standard defined by a recognized standards body, or, in the case of | ||||
| interfaces specified for a particular programming language, one that | ||||
| is widely used among developers working in that language. | ||||
|  | ||||
|   The "System Libraries" of an executable work include anything, other | ||||
| than the work as a whole, that (a) is included in the normal form of | ||||
| packaging a Major Component, but which is not part of that Major | ||||
| Component, and (b) serves only to enable use of the work with that | ||||
| Major Component, or to implement a Standard Interface for which an | ||||
| implementation is available to the public in source code form.  A | ||||
| "Major Component", in this context, means a major essential component | ||||
| (kernel, window system, and so on) of the specific operating system | ||||
| (if any) on which the executable work runs, or a compiler used to | ||||
| produce the work, or an object code interpreter used to run it. | ||||
|  | ||||
|   The "Corresponding Source" for a work in object code form means all | ||||
| the source code needed to generate, install, and (for an executable | ||||
| work) run the object code and to modify the work, including scripts to | ||||
| control those activities.  However, it does not include the work's | ||||
| System Libraries, or general-purpose tools or generally available free | ||||
| programs which are used unmodified in performing those activities but | ||||
| which are not part of the work.  For example, Corresponding Source | ||||
| includes interface definition files associated with source files for | ||||
| the work, and the source code for shared libraries and dynamically | ||||
| linked subprograms that the work is specifically designed to require, | ||||
| such as by intimate data communication or control flow between those | ||||
| subprograms and other parts of the work. | ||||
|  | ||||
|   The Corresponding Source need not include anything that users | ||||
| can regenerate automatically from other parts of the Corresponding | ||||
| Source. | ||||
|  | ||||
|   The Corresponding Source for a work in source code form is that | ||||
| same work. | ||||
|  | ||||
|   2. Basic Permissions. | ||||
|  | ||||
|   All rights granted under this License are granted for the term of | ||||
| copyright on the Program, and are irrevocable provided the stated | ||||
| conditions are met.  This License explicitly affirms your unlimited | ||||
| permission to run the unmodified Program.  The output from running a | ||||
| covered work is covered by this License only if the output, given its | ||||
| content, constitutes a covered work.  This License acknowledges your | ||||
| rights of fair use or other equivalent, as provided by copyright law. | ||||
|  | ||||
|   You may make, run and propagate covered works that you do not | ||||
| convey, without conditions so long as your license otherwise remains | ||||
| in force.  You may convey covered works to others for the sole purpose | ||||
| of having them make modifications exclusively for you, or provide you | ||||
| with facilities for running those works, provided that you comply with | ||||
| the terms of this License in conveying all material for which you do | ||||
| not control copyright.  Those thus making or running the covered works | ||||
| for you must do so exclusively on your behalf, under your direction | ||||
| and control, on terms that prohibit them from making any copies of | ||||
| your copyrighted material outside their relationship with you. | ||||
|  | ||||
|   Conveying under any other circumstances is permitted solely under | ||||
| the conditions stated below.  Sublicensing is not allowed; section 10 | ||||
| makes it unnecessary. | ||||
|  | ||||
|   3. Protecting Users' Legal Rights From Anti-Circumvention Law. | ||||
|  | ||||
|   No covered work shall be deemed part of an effective technological | ||||
| measure under any applicable law fulfilling obligations under article | ||||
| 11 of the WIPO copyright treaty adopted on 20 December 1996, or | ||||
| similar laws prohibiting or restricting circumvention of such | ||||
| measures. | ||||
|  | ||||
|   When you convey a covered work, you waive any legal power to forbid | ||||
| circumvention of technological measures to the extent such circumvention | ||||
| is effected by exercising rights under this License with respect to | ||||
| the covered work, and you disclaim any intention to limit operation or | ||||
| modification of the work as a means of enforcing, against the work's | ||||
| users, your or third parties' legal rights to forbid circumvention of | ||||
| technological measures. | ||||
|  | ||||
|   4. Conveying Verbatim Copies. | ||||
|  | ||||
|   You may convey verbatim copies of the Program's source code as you | ||||
| receive it, in any medium, provided that you conspicuously and | ||||
| appropriately publish on each copy an appropriate copyright notice; | ||||
| keep intact all notices stating that this License and any | ||||
| non-permissive terms added in accord with section 7 apply to the code; | ||||
| keep intact all notices of the absence of any warranty; and give all | ||||
| recipients a copy of this License along with the Program. | ||||
|  | ||||
|   You may charge any price or no price for each copy that you convey, | ||||
| and you may offer support or warranty protection for a fee. | ||||
|  | ||||
|   5. Conveying Modified Source Versions. | ||||
|  | ||||
|   You may convey a work based on the Program, or the modifications to | ||||
| produce it from the Program, in the form of source code under the | ||||
| terms of section 4, provided that you also meet all of these conditions: | ||||
|  | ||||
|     a) The work must carry prominent notices stating that you modified | ||||
|     it, and giving a relevant date. | ||||
|  | ||||
|     b) The work must carry prominent notices stating that it is | ||||
|     released under this License and any conditions added under section | ||||
|     7.  This requirement modifies the requirement in section 4 to | ||||
|     "keep intact all notices". | ||||
|  | ||||
|     c) You must license the entire work, as a whole, under this | ||||
|     License to anyone who comes into possession of a copy.  This | ||||
|     License will therefore apply, along with any applicable section 7 | ||||
|     additional terms, to the whole of the work, and all its parts, | ||||
|     regardless of how they are packaged.  This License gives no | ||||
|     permission to license the work in any other way, but it does not | ||||
|     invalidate such permission if you have separately received it. | ||||
|  | ||||
|     d) If the work has interactive user interfaces, each must display | ||||
|     Appropriate Legal Notices; however, if the Program has interactive | ||||
|     interfaces that do not display Appropriate Legal Notices, your | ||||
|     work need not make them do so. | ||||
|  | ||||
|   A compilation of a covered work with other separate and independent | ||||
| works, which are not by their nature extensions of the covered work, | ||||
| and which are not combined with it such as to form a larger program, | ||||
| in or on a volume of a storage or distribution medium, is called an | ||||
| "aggregate" if the compilation and its resulting copyright are not | ||||
| used to limit the access or legal rights of the compilation's users | ||||
| beyond what the individual works permit.  Inclusion of a covered work | ||||
| in an aggregate does not cause this License to apply to the other | ||||
| parts of the aggregate. | ||||
|  | ||||
|   6. Conveying Non-Source Forms. | ||||
|  | ||||
|   You may convey a covered work in object code form under the terms | ||||
| of sections 4 and 5, provided that you also convey the | ||||
| machine-readable Corresponding Source under the terms of this License, | ||||
| in one of these ways: | ||||
|  | ||||
|     a) Convey the object code in, or embodied in, a physical product | ||||
|     (including a physical distribution medium), accompanied by the | ||||
|     Corresponding Source fixed on a durable physical medium | ||||
|     customarily used for software interchange. | ||||
|  | ||||
|     b) Convey the object code in, or embodied in, a physical product | ||||
|     (including a physical distribution medium), accompanied by a | ||||
|     written offer, valid for at least three years and valid for as | ||||
|     long as you offer spare parts or customer support for that product | ||||
|     model, to give anyone who possesses the object code either (1) a | ||||
|     copy of the Corresponding Source for all the software in the | ||||
|     product that is covered by this License, on a durable physical | ||||
|     medium customarily used for software interchange, for a price no | ||||
|     more than your reasonable cost of physically performing this | ||||
|     conveying of source, or (2) access to copy the | ||||
|     Corresponding Source from a network server at no charge. | ||||
|  | ||||
|     c) Convey individual copies of the object code with a copy of the | ||||
|     written offer to provide the Corresponding Source.  This | ||||
|     alternative is allowed only occasionally and noncommercially, and | ||||
|     only if you received the object code with such an offer, in accord | ||||
|     with subsection 6b. | ||||
|  | ||||
|     d) Convey the object code by offering access from a designated | ||||
|     place (gratis or for a charge), and offer equivalent access to the | ||||
|     Corresponding Source in the same way through the same place at no | ||||
|     further charge.  You need not require recipients to copy the | ||||
|     Corresponding Source along with the object code.  If the place to | ||||
|     copy the object code is a network server, the Corresponding Source | ||||
|     may be on a different server (operated by you or a third party) | ||||
|     that supports equivalent copying facilities, provided you maintain | ||||
|     clear directions next to the object code saying where to find the | ||||
|     Corresponding Source.  Regardless of what server hosts the | ||||
|     Corresponding Source, you remain obligated to ensure that it is | ||||
|     available for as long as needed to satisfy these requirements. | ||||
|  | ||||
|     e) Convey the object code using peer-to-peer transmission, provided | ||||
|     you inform other peers where the object code and Corresponding | ||||
|     Source of the work are being offered to the general public at no | ||||
|     charge under subsection 6d. | ||||
|  | ||||
|   A separable portion of the object code, whose source code is excluded | ||||
| from the Corresponding Source as a System Library, need not be | ||||
| included in conveying the object code work. | ||||
|  | ||||
|   A "User Product" is either (1) a "consumer product", which means any | ||||
| tangible personal property which is normally used for personal, family, | ||||
| or household purposes, or (2) anything designed or sold for incorporation | ||||
| into a dwelling.  In determining whether a product is a consumer product, | ||||
| doubtful cases shall be resolved in favor of coverage.  For a particular | ||||
| product received by a particular user, "normally used" refers to a | ||||
| typical or common use of that class of product, regardless of the status | ||||
| of the particular user or of the way in which the particular user | ||||
| actually uses, or expects or is expected to use, the product.  A product | ||||
| is a consumer product regardless of whether the product has substantial | ||||
| commercial, industrial or non-consumer uses, unless such uses represent | ||||
| the only significant mode of use of the product. | ||||
|  | ||||
|   "Installation Information" for a User Product means any methods, | ||||
| procedures, authorization keys, or other information required to install | ||||
| and execute modified versions of a covered work in that User Product from | ||||
| a modified version of its Corresponding Source.  The information must | ||||
| suffice to ensure that the continued functioning of the modified object | ||||
| code is in no case prevented or interfered with solely because | ||||
| modification has been made. | ||||
|  | ||||
|   If you convey an object code work under this section in, or with, or | ||||
| specifically for use in, a User Product, and the conveying occurs as | ||||
| part of a transaction in which the right of possession and use of the | ||||
| User Product is transferred to the recipient in perpetuity or for a | ||||
| fixed term (regardless of how the transaction is characterized), the | ||||
| Corresponding Source conveyed under this section must be accompanied | ||||
| by the Installation Information.  But this requirement does not apply | ||||
| if neither you nor any third party retains the ability to install | ||||
| modified object code on the User Product (for example, the work has | ||||
| been installed in ROM). | ||||
|  | ||||
|   The requirement to provide Installation Information does not include a | ||||
| requirement to continue to provide support service, warranty, or updates | ||||
| for a work that has been modified or installed by the recipient, or for | ||||
| the User Product in which it has been modified or installed.  Access to a | ||||
| network may be denied when the modification itself materially and | ||||
| adversely affects the operation of the network or violates the rules and | ||||
| protocols for communication across the network. | ||||
|  | ||||
|   Corresponding Source conveyed, and Installation Information provided, | ||||
| in accord with this section must be in a format that is publicly | ||||
| documented (and with an implementation available to the public in | ||||
| source code form), and must require no special password or key for | ||||
| unpacking, reading or copying. | ||||
|  | ||||
|   7. Additional Terms. | ||||
|  | ||||
|   "Additional permissions" are terms that supplement the terms of this | ||||
| License by making exceptions from one or more of its conditions. | ||||
| Additional permissions that are applicable to the entire Program shall | ||||
| be treated as though they were included in this License, to the extent | ||||
| that they are valid under applicable law.  If additional permissions | ||||
| apply only to part of the Program, that part may be used separately | ||||
| under those permissions, but the entire Program remains governed by | ||||
| this License without regard to the additional permissions. | ||||
|  | ||||
|   When you convey a copy of a covered work, you may at your option | ||||
| remove any additional permissions from that copy, or from any part of | ||||
| it.  (Additional permissions may be written to require their own | ||||
| removal in certain cases when you modify the work.)  You may place | ||||
| additional permissions on material, added by you to a covered work, | ||||
| for which you have or can give appropriate copyright permission. | ||||
|  | ||||
|   Notwithstanding any other provision of this License, for material you | ||||
| add to a covered work, you may (if authorized by the copyright holders of | ||||
| that material) supplement the terms of this License with terms: | ||||
|  | ||||
|     a) Disclaiming warranty or limiting liability differently from the | ||||
|     terms of sections 15 and 16 of this License; or | ||||
|  | ||||
|     b) Requiring preservation of specified reasonable legal notices or | ||||
|     author attributions in that material or in the Appropriate Legal | ||||
|     Notices displayed by works containing it; or | ||||
|  | ||||
|     c) Prohibiting misrepresentation of the origin of that material, or | ||||
|     requiring that modified versions of such material be marked in | ||||
|     reasonable ways as different from the original version; or | ||||
|  | ||||
|     d) Limiting the use for publicity purposes of names of licensors or | ||||
|     authors of the material; or | ||||
|  | ||||
|     e) Declining to grant rights under trademark law for use of some | ||||
|     trade names, trademarks, or service marks; or | ||||
|  | ||||
|     f) Requiring indemnification of licensors and authors of that | ||||
|     material by anyone who conveys the material (or modified versions of | ||||
|     it) with contractual assumptions of liability to the recipient, for | ||||
|     any liability that these contractual assumptions directly impose on | ||||
|     those licensors and authors. | ||||
|  | ||||
|   All other non-permissive additional terms are considered "further | ||||
| restrictions" within the meaning of section 10.  If the Program as you | ||||
| received it, or any part of it, contains a notice stating that it is | ||||
| governed by this License along with a term that is a further | ||||
| restriction, you may remove that term.  If a license document contains | ||||
| a further restriction but permits relicensing or conveying under this | ||||
| License, you may add to a covered work material governed by the terms | ||||
| of that license document, provided that the further restriction does | ||||
| not survive such relicensing or conveying. | ||||
|  | ||||
|   If you add terms to a covered work in accord with this section, you | ||||
| must place, in the relevant source files, a statement of the | ||||
| additional terms that apply to those files, or a notice indicating | ||||
| where to find the applicable terms. | ||||
|  | ||||
|   Additional terms, permissive or non-permissive, may be stated in the | ||||
| form of a separately written license, or stated as exceptions; | ||||
| the above requirements apply either way. | ||||
|  | ||||
|   8. Termination. | ||||
|  | ||||
|   You may not propagate or modify a covered work except as expressly | ||||
| provided under this License.  Any attempt otherwise to propagate or | ||||
| modify it is void, and will automatically terminate your rights under | ||||
| this License (including any patent licenses granted under the third | ||||
| paragraph of section 11). | ||||
|  | ||||
|   However, if you cease all violation of this License, then your | ||||
| license from a particular copyright holder is reinstated (a) | ||||
| provisionally, unless and until the copyright holder explicitly and | ||||
| finally terminates your license, and (b) permanently, if the copyright | ||||
| holder fails to notify you of the violation by some reasonable means | ||||
| prior to 60 days after the cessation. | ||||
|  | ||||
|   Moreover, your license from a particular copyright holder is | ||||
| reinstated permanently if the copyright holder notifies you of the | ||||
| violation by some reasonable means, this is the first time you have | ||||
| received notice of violation of this License (for any work) from that | ||||
| copyright holder, and you cure the violation prior to 30 days after | ||||
| your receipt of the notice. | ||||
|  | ||||
|   Termination of your rights under this section does not terminate the | ||||
| licenses of parties who have received copies or rights from you under | ||||
| this License.  If your rights have been terminated and not permanently | ||||
| reinstated, you do not qualify to receive new licenses for the same | ||||
| material under section 10. | ||||
|  | ||||
|   9. Acceptance Not Required for Having Copies. | ||||
|  | ||||
|   You are not required to accept this License in order to receive or | ||||
| run a copy of the Program.  Ancillary propagation of a covered work | ||||
| occurring solely as a consequence of using peer-to-peer transmission | ||||
| to receive a copy likewise does not require acceptance.  However, | ||||
| nothing other than this License grants you permission to propagate or | ||||
| modify any covered work.  These actions infringe copyright if you do | ||||
| not accept this License.  Therefore, by modifying or propagating a | ||||
| covered work, you indicate your acceptance of this License to do so. | ||||
|  | ||||
|   10. Automatic Licensing of Downstream Recipients. | ||||
|  | ||||
|   Each time you convey a covered work, the recipient automatically | ||||
| receives a license from the original licensors, to run, modify and | ||||
| propagate that work, subject to this License.  You are not responsible | ||||
| for enforcing compliance by third parties with this License. | ||||
|  | ||||
|   An "entity transaction" is a transaction transferring control of an | ||||
| organization, or substantially all assets of one, or subdividing an | ||||
| organization, or merging organizations.  If propagation of a covered | ||||
| work results from an entity transaction, each party to that | ||||
| transaction who receives a copy of the work also receives whatever | ||||
| licenses to the work the party's predecessor in interest had or could | ||||
| give under the previous paragraph, plus a right to possession of the | ||||
| Corresponding Source of the work from the predecessor in interest, if | ||||
| the predecessor has it or can get it with reasonable efforts. | ||||
|  | ||||
|   You may not impose any further restrictions on the exercise of the | ||||
| rights granted or affirmed under this License.  For example, you may | ||||
| not impose a license fee, royalty, or other charge for exercise of | ||||
| rights granted under this License, and you may not initiate litigation | ||||
| (including a cross-claim or counterclaim in a lawsuit) alleging that | ||||
| any patent claim is infringed by making, using, selling, offering for | ||||
| sale, or importing the Program or any portion of it. | ||||
|  | ||||
|   11. Patents. | ||||
|  | ||||
|   A "contributor" is a copyright holder who authorizes use under this | ||||
| License of the Program or a work on which the Program is based.  The | ||||
| work thus licensed is called the contributor's "contributor version". | ||||
|  | ||||
|   A contributor's "essential patent claims" are all patent claims | ||||
| owned or controlled by the contributor, whether already acquired or | ||||
| hereafter acquired, that would be infringed by some manner, permitted | ||||
| by this License, of making, using, or selling its contributor version, | ||||
| but do not include claims that would be infringed only as a | ||||
| consequence of further modification of the contributor version.  For | ||||
| purposes of this definition, "control" includes the right to grant | ||||
| patent sublicenses in a manner consistent with the requirements of | ||||
| this License. | ||||
|  | ||||
|   Each contributor grants you a non-exclusive, worldwide, royalty-free | ||||
| patent license under the contributor's essential patent claims, to | ||||
| make, use, sell, offer for sale, import and otherwise run, modify and | ||||
| propagate the contents of its contributor version. | ||||
|  | ||||
|   In the following three paragraphs, a "patent license" is any express | ||||
| agreement or commitment, however denominated, not to enforce a patent | ||||
| (such as an express permission to practice a patent or covenant not to | ||||
| sue for patent infringement).  To "grant" such a patent license to a | ||||
| party means to make such an agreement or commitment not to enforce a | ||||
| patent against the party. | ||||
|  | ||||
|   If you convey a covered work, knowingly relying on a patent license, | ||||
| and the Corresponding Source of the work is not available for anyone | ||||
| to copy, free of charge and under the terms of this License, through a | ||||
| publicly available network server or other readily accessible means, | ||||
| then you must either (1) cause the Corresponding Source to be so | ||||
| available, or (2) arrange to deprive yourself of the benefit of the | ||||
| patent license for this particular work, or (3) arrange, in a manner | ||||
| consistent with the requirements of this License, to extend the patent | ||||
| license to downstream recipients.  "Knowingly relying" means you have | ||||
| actual knowledge that, but for the patent license, your conveying the | ||||
| covered work in a country, or your recipient's use of the covered work | ||||
| in a country, would infringe one or more identifiable patents in that | ||||
| country that you have reason to believe are valid. | ||||
|  | ||||
|   If, pursuant to or in connection with a single transaction or | ||||
| arrangement, you convey, or propagate by procuring conveyance of, a | ||||
| covered work, and grant a patent license to some of the parties | ||||
| receiving the covered work authorizing them to use, propagate, modify | ||||
| or convey a specific copy of the covered work, then the patent license | ||||
| you grant is automatically extended to all recipients of the covered | ||||
| work and works based on it. | ||||
|  | ||||
|   A patent license is "discriminatory" if it does not include within | ||||
| the scope of its coverage, prohibits the exercise of, or is | ||||
| conditioned on the non-exercise of one or more of the rights that are | ||||
| specifically granted under this License.  You may not convey a covered | ||||
| work if you are a party to an arrangement with a third party that is | ||||
| in the business of distributing software, under which you make payment | ||||
| to the third party based on the extent of your activity of conveying | ||||
| the work, and under which the third party grants, to any of the | ||||
| parties who would receive the covered work from you, a discriminatory | ||||
| patent license (a) in connection with copies of the covered work | ||||
| conveyed by you (or copies made from those copies), or (b) primarily | ||||
| for and in connection with specific products or compilations that | ||||
| contain the covered work, unless you entered into that arrangement, | ||||
| or that patent license was granted, prior to 28 March 2007. | ||||
|  | ||||
|   Nothing in this License shall be construed as excluding or limiting | ||||
| any implied license or other defenses to infringement that may | ||||
| otherwise be available to you under applicable patent law. | ||||
|  | ||||
|   12. No Surrender of Others' Freedom. | ||||
|  | ||||
|   If conditions are imposed on you (whether by court order, agreement or | ||||
| otherwise) that contradict the conditions of this License, they do not | ||||
| excuse you from the conditions of this License.  If you cannot convey a | ||||
| covered work so as to satisfy simultaneously your obligations under this | ||||
| License and any other pertinent obligations, then as a consequence you may | ||||
| not convey it at all.  For example, if you agree to terms that obligate you | ||||
| to collect a royalty for further conveying from those to whom you convey | ||||
| the Program, the only way you could satisfy both those terms and this | ||||
| License would be to refrain entirely from conveying the Program. | ||||
|  | ||||
|   13. Use with the GNU Affero General Public License. | ||||
|  | ||||
|   Notwithstanding any other provision of this License, you have | ||||
| permission to link or combine any covered work with a work licensed | ||||
| under version 3 of the GNU Affero General Public License into a single | ||||
| combined work, and to convey the resulting work.  The terms of this | ||||
| License will continue to apply to the part which is the covered work, | ||||
| but the special requirements of the GNU Affero General Public License, | ||||
| section 13, concerning interaction through a network will apply to the | ||||
| combination as such. | ||||
|  | ||||
|   14. Revised Versions of this License. | ||||
|  | ||||
|   The Free Software Foundation may publish revised and/or new versions of | ||||
| the GNU General Public License from time to time.  Such new versions will | ||||
| be similar in spirit to the present version, but may differ in detail to | ||||
| address new problems or concerns. | ||||
|  | ||||
|   Each version is given a distinguishing version number.  If the | ||||
| Program specifies that a certain numbered version of the GNU General | ||||
| Public License "or any later version" applies to it, you have the | ||||
| option of following the terms and conditions either of that numbered | ||||
| version or of any later version published by the Free Software | ||||
| Foundation.  If the Program does not specify a version number of the | ||||
| GNU General Public License, you may choose any version ever published | ||||
| by the Free Software Foundation. | ||||
|  | ||||
|   If the Program specifies that a proxy can decide which future | ||||
| versions of the GNU General Public License can be used, that proxy's | ||||
| public statement of acceptance of a version permanently authorizes you | ||||
| to choose that version for the Program. | ||||
|  | ||||
|   Later license versions may give you additional or different | ||||
| permissions.  However, no additional obligations are imposed on any | ||||
| author or copyright holder as a result of your choosing to follow a | ||||
| later version. | ||||
|  | ||||
|   15. Disclaimer of Warranty. | ||||
|  | ||||
|   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | ||||
| APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | ||||
| HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | ||||
| OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | ||||
| THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
| PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | ||||
| IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | ||||
| ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | ||||
|  | ||||
|   16. Limitation of Liability. | ||||
|  | ||||
|   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||||
| WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | ||||
| THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | ||||
| GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | ||||
| USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | ||||
| DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | ||||
| PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | ||||
| EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | ||||
| SUCH DAMAGES. | ||||
|  | ||||
|   17. Interpretation of Sections 15 and 16. | ||||
|  | ||||
|   If the disclaimer of warranty and limitation of liability provided | ||||
| above cannot be given local legal effect according to their terms, | ||||
| reviewing courts shall apply local law that most closely approximates | ||||
| an absolute waiver of all civil liability in connection with the | ||||
| Program, unless a warranty or assumption of liability accompanies a | ||||
| copy of the Program in return for a fee. | ||||
|  | ||||
|                      END OF TERMS AND CONDITIONS | ||||
|  | ||||
|             How to Apply These Terms to Your New Programs | ||||
|  | ||||
|   If you develop a new program, and you want it to be of the greatest | ||||
| possible use to the public, the best way to achieve this is to make it | ||||
| free software which everyone can redistribute and change under these terms. | ||||
|  | ||||
|   To do so, attach the following notices to the program.  It is safest | ||||
| to attach them to the start of each source file to most effectively | ||||
| state the exclusion of warranty; and each file should have at least | ||||
| the "copyright" line and a pointer to where the full notice is found. | ||||
|  | ||||
|     <one line to give the program's name and a brief idea of what it does.> | ||||
|     Copyright (C) <year>  <name of author> | ||||
|  | ||||
|     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/>. | ||||
|  | ||||
| Also add information on how to contact you by electronic and paper mail. | ||||
|  | ||||
|   If the program does terminal interaction, make it output a short | ||||
| notice like this when it starts in an interactive mode: | ||||
|  | ||||
|     <program>  Copyright (C) <year>  <name of author> | ||||
|     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||
|     This is free software, and you are welcome to redistribute it | ||||
|     under certain conditions; type `show c' for details. | ||||
|  | ||||
| The hypothetical commands `show w' and `show c' should show the appropriate | ||||
| parts of the General Public License.  Of course, your program's commands | ||||
| might be different; for a GUI interface, you would use an "about box". | ||||
|  | ||||
|   You should also get your employer (if you work as a programmer) or school, | ||||
| if any, to sign a "copyright disclaimer" for the program, if necessary. | ||||
| For more information on this, and how to apply and follow the GNU GPL, see | ||||
| <http://www.gnu.org/licenses/>. | ||||
|  | ||||
|   The GNU General Public License does not permit incorporating your program | ||||
| into proprietary programs.  If your program is a subroutine library, you | ||||
| may consider it more useful to permit linking proprietary applications with | ||||
| the library.  If this is what you want to do, use the GNU Lesser General | ||||
| Public License instead of this License.  But first, please read | ||||
| <http://www.gnu.org/philosophy/why-not-lgpl.html>. | ||||
| @@ -0,0 +1,28 @@ | ||||
| FTDI EVE Library | ||||
| ---------------- | ||||
|  | ||||
| The FTDI EVE Library is a fully open-source library and UI framework for the FTDI | ||||
| FT800 and FT810 graphics processor. | ||||
|  | ||||
| Although the library has been developed within Lulzbot for providing a user interface | ||||
| for Marlin, the library has been written so that it can be used in any Arduino sketch. | ||||
|  | ||||
| The library is split into two parts. The "basic" API provides a shallow interface to | ||||
| the underlying FTDI hardware and command FIFO and provides low-level access to the | ||||
| hardware as closely as possible to the API described in the FTDI Programmer's Guide. | ||||
|  | ||||
| The "extended" API builds on top of the "basic" API to provide a GUI framework for | ||||
| handling common challenges in building a usable GUI. The GUI framework provides the | ||||
| following features: | ||||
|  | ||||
| - Macros for a resolution-independent placement of widgets based on a grid. | ||||
| - Class-based UI screens, with press and unpress touch events, as well as touch repeat. | ||||
| - Event loop with button debouncing and button push visual and auditory feedback. | ||||
| - Easy screen-to-screen navigation including a navigation stack for going backwards. | ||||
| - Visual feedback for disabled vs enabled buttons, and custom button styles. | ||||
| - A sound player class for playing individual notes or complete sound sequences. | ||||
| - Display list caching, for storing static background elements of a screen in RAM_G. | ||||
|  | ||||
| See the "examples" folder for Arduino sketches. Modify the "src/config.h" file in | ||||
| each to suit your particular setup. The "sample_configs" contain sample configuration | ||||
| files for running the sketches on our 3D printer boards. | ||||
| @@ -0,0 +1,183 @@ | ||||
| /************ | ||||
|  * boards.h * | ||||
|  ************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #define HAS_RESOLUTION (defined(TOUCH_UI_320x240) || defined(TOUCH_UI_480x272) || defined(TOUCH_UI_800x480)) | ||||
|  | ||||
| #define IS_FT800 \ | ||||
|     constexpr uint16_t ftdi_chip = 800; \ | ||||
|     using namespace FTDI_FT800; \ | ||||
|     namespace DL { \ | ||||
|       using namespace FTDI_FT800_DL; \ | ||||
|     } \ | ||||
|     typedef ft800_memory_map ftdi_memory_map; \ | ||||
|     typedef ft800_registers  ftdi_registers; | ||||
|  | ||||
| #define IS_FT810 \ | ||||
|     constexpr uint16_t ftdi_chip = 810; \ | ||||
|     using namespace FTDI_FT810; \ | ||||
|     namespace DL { \ | ||||
|       using namespace FTDI_FT800_DL; \ | ||||
|       using namespace FTDI_FT810_DL; \ | ||||
|     } \ | ||||
|     typedef ft810_memory_map ftdi_memory_map; \ | ||||
|     typedef ft810_registers  ftdi_registers; | ||||
|  | ||||
|  | ||||
| #ifdef LCD_FTDI_VM800B35A | ||||
|   #if !HAS_RESOLUTION | ||||
|     #define TOUCH_UI_320x240 | ||||
|   #endif | ||||
|   #ifndef FTDI_API_LEVEL | ||||
|     #define FTDI_API_LEVEL                800 | ||||
|   #endif | ||||
|   namespace FTDI { | ||||
|     IS_FT800 | ||||
|     constexpr bool Use_Crystal              = true;  // 0 = use internal oscillator, 1 = module has a crystal populated | ||||
|     constexpr bool GPIO_0_Audio_Enable      = false; /* 1 = does use GPIO00 for amplifier control, 0 = not in use for Audio */ | ||||
|     constexpr bool GPIO_1_Audio_Shutdown    = true;  /* 1 = does use GPIO01 for amplifier control, 0 = not in use for Audio */ | ||||
|     constexpr uint8_t Swizzle               = 2; | ||||
|     constexpr uint8_t CSpread               = 1; | ||||
|  | ||||
|     constexpr uint16_t touch_threshold      = 1200; /* touch-sensitivity */ | ||||
|   } | ||||
|  | ||||
| /* | ||||
|  * Settings for the Haoyu Electronics, 4.3" Graphical LCD Touchscreen,       480x272, SPI, FT800 (FT800CB-HY43B) | ||||
|  *                  Haoyu Electronics,   5" Graphical LCD Touchscreen,       480x272, SPI, FT800 (FT800CB-HY50B) | ||||
|  * | ||||
|  *    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 | ||||
|  * | ||||
|  * 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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #elif defined(LCD_HAOYU_FT800CB) | ||||
|   #if !HAS_RESOLUTION | ||||
|     #define TOUCH_UI_480x272 | ||||
|   #endif | ||||
|   #ifndef FTDI_API_LEVEL | ||||
|     #define FTDI_API_LEVEL                800 | ||||
|   #endif | ||||
|   namespace FTDI { | ||||
|     IS_FT800 | ||||
|     constexpr bool Use_Crystal              = true; // 0 = use internal oscillator, 1 = module has a crystal populated | ||||
|     constexpr bool GPIO_0_Audio_Enable      = false; | ||||
|     constexpr bool GPIO_1_Audio_Shutdown    = false; | ||||
|     constexpr uint8_t Swizzle               = 0; | ||||
|     constexpr uint8_t CSpread               = 1; | ||||
|     constexpr uint16_t touch_threshold      = 2000; /* touch-sensitivity */ | ||||
|   } | ||||
|  | ||||
| /* | ||||
|  * 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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #elif defined(LCD_HAOYU_FT810CB) | ||||
|   #if !HAS_RESOLUTION | ||||
|     #define TOUCH_UI_800x480 | ||||
|   #endif | ||||
|   #ifndef FTDI_API_LEVEL | ||||
|     #define FTDI_API_LEVEL                810 | ||||
|   #endif | ||||
|   namespace FTDI { | ||||
|     IS_FT810 | ||||
|     constexpr bool Use_Crystal              = true; // 0 = use internal oscillator, 1 = module has a crystal populated | ||||
|     constexpr bool GPIO_0_Audio_Enable      = false; | ||||
|     constexpr bool GPIO_1_Audio_Shutdown    = false; | ||||
|     constexpr uint8_t Swizzle               = 0; | ||||
|     constexpr uint8_t CSpread               = 1; | ||||
|     constexpr uint16_t touch_threshold      = 2000; /* touch-sensitivity */ | ||||
|   } | ||||
|  | ||||
| /* | ||||
|  * Settings for the 4D Systems,        4.3" Embedded SPI Display             480x272, SPI, FT800 (4DLCD-FT843) | ||||
|  * | ||||
|  *    http://www.4dsystems.com.au/product/4DLCD_FT843/ | ||||
|  * | ||||
|  * Datasheet: | ||||
|  * | ||||
|  *    http://www.4dsystems.com.au/productpages/4DLCD-FT843/downloads/FT843-4.3-Display_datasheet_R_1_2.pdf | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #elif defined(LCD_4DSYSTEMS_4DLCD_FT843) | ||||
|   #if !HAS_RESOLUTION | ||||
|     #define TOUCH_UI_480x272 | ||||
|   #endif | ||||
|   #ifndef FTDI_API_LEVEL | ||||
|     #define FTDI_API_LEVEL                800 | ||||
|   #endif | ||||
|   namespace FTDI { | ||||
|     IS_FT800 | ||||
|     constexpr bool Use_Crystal              = true; // 0 = use internal oscillator, 1 = module has a crystal populated | ||||
|     constexpr bool GPIO_0_Audio_Enable      = false; | ||||
|     constexpr bool GPIO_1_Audio_Shutdown    = true; | ||||
|     constexpr uint8_t Swizzle               = 0; | ||||
|     constexpr uint8_t CSpread               = 1; | ||||
|     constexpr uint16_t touch_threshold      = 1200; /* touch-sensitivity */ | ||||
|   } | ||||
|  | ||||
| /* | ||||
|  * Settings for the Aleph Objects Color LCD User Interface | ||||
|  * | ||||
|  *    https://code.alephobjects.com/source/aotctl/ | ||||
|  * | ||||
|  * Datasheet: | ||||
|  * | ||||
|  *    http://www.hantronix.com/files/data/s1501799605s500-gh7.pdf | ||||
|  * | ||||
|  */ | ||||
| #elif defined(LCD_ALEPHOBJECTS_CLCD_UI) | ||||
|   #if !HAS_RESOLUTION | ||||
|     #define TOUCH_UI_800x480 | ||||
|   #endif | ||||
|   #ifndef FTDI_API_LEVEL | ||||
|     #define FTDI_API_LEVEL                810 | ||||
|   #endif | ||||
|   namespace FTDI { | ||||
|     IS_FT810 | ||||
|     constexpr bool Use_Crystal              = false; // 0 = use internal oscillator, 1 = module has a crystal populated | ||||
|     constexpr bool GPIO_0_Audio_Enable      = true;  // The AO CLCD uses GPIO0 to enable audio | ||||
|     constexpr bool GPIO_1_Audio_Shutdown    = false; | ||||
|     constexpr uint8_t Swizzle               = 0; | ||||
|     constexpr uint8_t CSpread               = 0; | ||||
|     constexpr uint16_t touch_threshold      = 2000; /* touch-sensitivity */ | ||||
|   } | ||||
|  | ||||
| #else | ||||
|  | ||||
|   #error Unknown or no LULZBOT_TOUCH_UI board specified. To add a new board, modify "ftdi_eve_boards.h" | ||||
| #endif | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,258 @@ | ||||
| /**************** | ||||
|  * commands.cpp * | ||||
|  ****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
|   /**************************************************************************** | ||||
|   *                       FUNCTION MAP                                        * | ||||
|   *                                                                           * | ||||
|   * SPI and FT800/810 Commands                                                * | ||||
|   *                                                                           * | ||||
|   * CLCD::spi_select()                 Set CS line to 0                       * | ||||
|   * CLCD::spi_deselect()               Set CS Line to 1                       * | ||||
|   * CLCD::reset()                      Toggle FT800/810 Power Down Line 50 ms * | ||||
|   * CLCD::spi_init()                   Configure I/O Lines for SPI            * | ||||
|   * CLCD::spi_transfer()               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_read_addr()              Send 32-Bit Address                    * | ||||
|   * CLCD::mem_read_8()                 Read 1 Byte                            * | ||||
|   * CLCD::mem_read_16()                Read 2 Bytes                           * | ||||
|   * CLCD::mem_read_32()                Read 4 Bytes                           * | ||||
|   *                                                                           * | ||||
|   * MEMORY WRITE FUNCTIONS                                                    * | ||||
|   *                                                                           * | ||||
|   * CLCD::mem_write_addr()             Send 24-Bit Address                    * | ||||
|   * CLCD::mem_write_8()                Write 1 Byte                           * | ||||
|   * CLCD::mem_write_16()               Write 2 Bytes                          * | ||||
|   * CLCD::mem_write_32()               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::str()                        Send Text String in 32-Bit Multiples   * | ||||
|  | ||||
|   *                                                                           * | ||||
|   * FT800/810 GRAPHIC COMMANDS                                                * | ||||
|   *                                                                           * | ||||
|   * class CLCD:CommandFifo {}          Class to control Cmd FIFO              * | ||||
|  | ||||
|   * CommandFifo::start()               Wait for CP finish - Set FIFO Ptr      * | ||||
|   * CommandFifo::execute()             Set REG_CMD_WRITE and start CP         * | ||||
|   * CommandFifo::reset()               Set Cmd Buffer Pointers to 0           * | ||||
|   * | ||||
|   * CommandFifo::fgcolor               Set Graphic Item Foreground Color      * | ||||
|   * CommandFifo::bgcolor               Set Graphic Item Background Color      * | ||||
|   * CommandFifo::begin()               Begin Drawing a Primative              * | ||||
|   * CommandFifo::mem_copy()            Copy a Block of Memory                 * | ||||
|   * CommandFifo::append()              Append Commands to Current DL          * | ||||
|   * CommandFifo::gradient_color()      Set 3D Button Highlight Color          * | ||||
|   * CommandFifo::button()              Draw Button with Bulk Write            * | ||||
|   * CommandFifo::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)             * | ||||
|   **************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| typedef const __FlashStringHelper *progmem_str; | ||||
|  | ||||
| class UIStorage; | ||||
|  | ||||
| class CLCD { | ||||
|   friend class UIStorage; | ||||
|  | ||||
|   public: | ||||
|     typedef FTDI::ftdi_registers  REG; | ||||
|     typedef FTDI::ftdi_memory_map MAP; | ||||
|  | ||||
|     static void     spi_write_addr (uint32_t reg_address); | ||||
|     static void     spi_read_addr  (uint32_t reg_address); | ||||
|  | ||||
|     static uint8_t  mem_read_8     (uint32_t reg_address); | ||||
|     static uint16_t mem_read_16    (uint32_t reg_address); | ||||
|     static uint32_t mem_read_32    (uint32_t reg_address); | ||||
|     static void     mem_read_bulk  (uint32_t reg_address, uint8_t *data, uint16_t len); | ||||
|  | ||||
|     static void     mem_write_8    (uint32_t reg_address, uint8_t w_data); | ||||
|     static void     mem_write_16   (uint32_t reg_address, uint16_t w_data); | ||||
|     static void     mem_write_32   (uint32_t reg_address, uint32_t w_data); | ||||
|     static void     mem_write_bulk (uint32_t reg_address, const void *data, uint16_t len, uint8_t padding = 0); | ||||
|     static void     mem_write_pgm  (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); | ||||
|     static void     mem_write_xbm  (uint32_t reg_address, progmem_str str, uint16_t len, uint8_t padding = 0); | ||||
|  | ||||
|   public: | ||||
|     class CommandFifo; | ||||
|     class FontMetrics; | ||||
|  | ||||
|     static void init (void); | ||||
|     static void default_touch_transform (void); | ||||
|     static void default_display_orientation (void); | ||||
|     static void turn_on_backlight (void); | ||||
|     static void enable (void); | ||||
|     static void disable (void); | ||||
|     static void set_brightness (uint8_t brightness); | ||||
|     static uint8_t get_brightness(); | ||||
|     static void host_cmd (unsigned char host_command, unsigned char byte2); | ||||
|  | ||||
|     static void get_font_metrics (uint8_t font, struct FontMetrics &fm); | ||||
|     static uint16_t get_text_width(const uint8_t font, const char *str); | ||||
|     static uint16_t get_text_width_P(const uint8_t font, const char *str); | ||||
|  | ||||
|     static uint8_t get_tag ()     {return mem_read_8(REG::TOUCH_TAG);} | ||||
|     static bool is_touching ()    {return (mem_read_32(REG::TOUCH_DIRECT_XY) & 0x80000000) == 0;} | ||||
|  | ||||
|     static uint8_t get_tracker (uint16_t &value) { | ||||
|       uint32_t tracker = mem_read_32(REG::TRACKER); | ||||
|       value            = tracker >> 16; | ||||
|       return tracker & 0xFF; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /*************************** FT800/810 Font Metrics ****************************/ | ||||
|  | ||||
| class CLCD::FontMetrics { | ||||
|   public: | ||||
|     uint8_t   char_widths[128]; | ||||
|     uint32_t  format; | ||||
|     uint32_t  stride; | ||||
|     uint32_t  width; | ||||
|     uint32_t  height; | ||||
|     uint32_t  ptr; | ||||
|  | ||||
|     FontMetrics(uint8_t font) {load(font);} | ||||
|  | ||||
|     void load(uint8_t font); | ||||
|  | ||||
|     // Returns width of string, up to a maximum of n characters. | ||||
|     uint16_t get_text_width(const char *str, size_t n = SIZE_MAX) const; | ||||
|     uint16_t get_text_width_P(const char *str, size_t n = SIZE_MAX) const; | ||||
| }; | ||||
|  | ||||
| /******************* FT800/810 Graphic Commands *********************************/ | ||||
|  | ||||
| class CLCD::CommandFifo { | ||||
|   protected: | ||||
|     #if FTDI_API_LEVEL >= 810 | ||||
|       uint32_t getRegCmdBSpace(); | ||||
|     #else | ||||
|       static uint32_t command_write_ptr; | ||||
|       template <class T> bool _write_unaligned(T data, uint16_t len); | ||||
|     #endif | ||||
|     void start(void); | ||||
|  | ||||
|   public: | ||||
|     template <class T> bool write(T data, uint16_t len); | ||||
|  | ||||
|   public: | ||||
|     CommandFifo() {start();} | ||||
|  | ||||
|     static void reset (void); | ||||
|     static bool is_processing(); | ||||
|     static bool has_fault(); | ||||
|  | ||||
|     void execute(void); | ||||
|  | ||||
|     void cmd(uint32_t cmd32); | ||||
|     void cmd(void* data, uint16_t len); | ||||
|  | ||||
|     void dlstart()      {cmd(FTDI::CMD_DLSTART);} | ||||
|     void swap()         {cmd(FTDI::CMD_SWAP);} | ||||
|     void coldstart()    {cmd(FTDI::CMD_COLDSTART);} | ||||
|     void screensaver()  {cmd(FTDI::CMD_SCREENSAVER);} | ||||
|     void stop()         {cmd(FTDI::CMD_STOP);} | ||||
|     void loadidentity() {cmd(FTDI::CMD_LOADIDENTITY);} | ||||
|     void setmatrix()    {cmd(FTDI::CMD_SETMATRIX);} | ||||
|  | ||||
|     void fgcolor     (uint32_t rgb); | ||||
|     void bgcolor     (uint32_t rgb); | ||||
|     void gradcolor   (uint32_t rgb); | ||||
|  | ||||
|     void track       (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t tag); | ||||
|     void clock       (int16_t x, int16_t y, int16_t r,            uint16_t options, int16_t h, int16_t m, int16_t s, int16_t ms); | ||||
|     void gauge       (int16_t x, int16_t y, int16_t r,            uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range); | ||||
|     void dial        (int16_t x, int16_t y, int16_t r,            uint16_t options, uint16_t val); | ||||
|     void slider      (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range); | ||||
|     void progress    (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range); | ||||
|     void scrollbar   (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t size, uint16_t range); | ||||
|     void number      (int16_t x, int16_t y, int16_t font, uint16_t options, int32_t n); | ||||
|     void spinner     (int16_t x, int16_t y, uint16_t style, uint16_t scale); | ||||
|     void sketch      (int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format); | ||||
|     void gradient    (int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1); | ||||
|     void snapshot    (uint32_t ptr); | ||||
|     void loadimage   (uint32_t ptr, uint32_t options); | ||||
|     void getprops    (uint32_t ptr, uint32_t width, uint32_t height); | ||||
|  | ||||
|     void scale       (int32_t sx, int32_t sy); | ||||
|     void rotate      (int32_t a); | ||||
|     void translate   (int32_t tx, int32_t ty); | ||||
|  | ||||
|     #if FTDI_API_LEVEL >= 810 | ||||
|       void setbase   (uint8_t base); | ||||
|       void setrotate (uint8_t rotation); | ||||
|       void setbitmap (uint32_t ptr, uint16_t fmt, uint16_t w, uint16_t h); | ||||
|       void snapshot2 (uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, uint16_t w, uint16_t h); | ||||
|       void mediafifo (uint32_t ptr, uint32_t size); | ||||
|       void playvideo (uint32_t options); | ||||
|       void videostart(); | ||||
|       void videoframe(uint32_t dst, uint32_t ptr); | ||||
|     #endif | ||||
|  | ||||
|     // All the following must be followed by str() | ||||
|     void text      (int16_t x, int16_t y,                       int16_t font, uint16_t options); | ||||
|     void button    (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t option); | ||||
|     void toggle    (int16_t x, int16_t y, int16_t w,            int16_t font, uint16_t options, bool state); | ||||
|     void keys      (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options); | ||||
|  | ||||
|     // Sends the string portion of text, button, toggle and keys. | ||||
|     void str (const char * data); | ||||
|     void str (progmem_str data); | ||||
|  | ||||
|     void memzero  (uint32_t ptr, uint32_t size); | ||||
|     void memset   (uint32_t ptr, uint32_t value, uint32_t size); | ||||
|     void memcpy   (uint32_t dst, uint32_t src, uint32_t size); | ||||
|     void memcrc   (uint32_t ptr, uint32_t num, uint32_t result); | ||||
|     void memwrite (uint32_t ptr, uint32_t value); | ||||
|     void inflate  (uint32_t ptr); | ||||
|     void getptr   (uint32_t result); | ||||
|     void append   (uint32_t ptr, uint32_t size); | ||||
| }; | ||||
| @@ -0,0 +1,411 @@ | ||||
| /*************** | ||||
|  * constants.h * | ||||
|  ***************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * This header defines constants and commands for the FTDI FT810 LCD Driver * | ||||
|  * chip.                                                                    * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| // OPTIONS | ||||
|  | ||||
| namespace FTDI { | ||||
|   constexpr uint16_t OPT_3D           = 0x0000; | ||||
|   constexpr uint16_t OPT_RGB565       = 0x0000; | ||||
|   constexpr uint16_t OPT_MONO         = 0x0001; | ||||
|   constexpr uint16_t OPT_NODL         = 0x0002; | ||||
|   constexpr uint16_t OPT_FLAT         = 0x0100; | ||||
|   constexpr uint16_t OPT_SIGNED       = 0x0100; | ||||
|   constexpr uint16_t OPT_CENTERX      = 0x0200; | ||||
|   constexpr uint16_t OPT_CENTERY      = 0x0400; | ||||
|   constexpr uint16_t OPT_CENTER       = (OPT_CENTERX | OPT_CENTERY); | ||||
|   constexpr uint16_t OPT_RIGHTX       = 0x0800; | ||||
|   constexpr uint16_t OPT_NOBACK       = 0x1000; | ||||
|   constexpr uint16_t OPT_NOTICKS      = 0x2000; | ||||
|   constexpr uint16_t OPT_NOHM         = 0x4000; | ||||
|   constexpr uint16_t OPT_NOPOINTER    = 0x4000; | ||||
|   constexpr uint16_t OPT_NOSECS       = 0x8000; | ||||
|   constexpr uint16_t OPT_NOHANDS      = (OPT_NOPOINTER | OPT_NOSECS); | ||||
| } | ||||
|  | ||||
| namespace FTDI_FT810 { | ||||
|   constexpr uint16_t OPT_NOTEAR      = 0x0004; | ||||
|   constexpr uint16_t OPT_FULLSCREEN  = 0x0008; | ||||
|   constexpr uint16_t OPT_MEDIAFIFO   = 0x0010; | ||||
|   constexpr uint16_t OPT_SOUND       = 0x0020; | ||||
| } | ||||
|  | ||||
| // GPIO Bits | ||||
|  | ||||
| namespace FTDI { | ||||
|   constexpr uint8_t GPIO_GP0         = 1 << 0; | ||||
|   constexpr uint8_t GPIO_GP1         = 1 << 1; | ||||
|   constexpr uint8_t GPIO_DISP        = 1 << 7; | ||||
| } | ||||
|  | ||||
| namespace FTDI_FT810 { | ||||
|   constexpr uint16_t GPIOX_GP0       = 1 << 0; | ||||
|   constexpr uint16_t GPIOX_GP1       = 1 << 1; | ||||
|   constexpr uint16_t GPIOX_DISP      = 1 << 15; | ||||
| } | ||||
|  | ||||
| // HOST COMMANDS | ||||
|  | ||||
| namespace FTDI { | ||||
|   constexpr uint8_t ACTIVE  = 0x00; | ||||
|   constexpr uint8_t STANDBY = 0x41; | ||||
|   constexpr uint8_t SLEEP   = 0x42; | ||||
|   constexpr uint8_t PWRDOWN = 0x50; | ||||
|   constexpr uint8_t CLKEXT  = 0x44; | ||||
|   constexpr uint8_t CLKINT  = 0x48; | ||||
|   constexpr uint8_t CORESET = 0x68; | ||||
| } | ||||
|  | ||||
| namespace FTDI_FT800 { | ||||
|     constexpr uint8_t CLK48M  = 0x62; | ||||
|     constexpr uint8_t CLK36M  = 0x61; | ||||
| } | ||||
|  | ||||
| namespace FTDI_FT810 { | ||||
|     constexpr uint8_t CLKSEL  = 0x61; | ||||
| } | ||||
|  | ||||
| // DISPLAY LIST COMMANDS | ||||
|  | ||||
| namespace FTDI { | ||||
|   constexpr uint8_t ARGB1555                           = 0; | ||||
|   constexpr uint8_t L1                                 = 1; | ||||
|   constexpr uint8_t L4                                 = 2; | ||||
|   constexpr uint8_t L8                                 = 3; | ||||
|   constexpr uint8_t RGB332                             = 4; | ||||
|   constexpr uint8_t ARGB2                              = 5; | ||||
|   constexpr uint8_t ARGB4                              = 6; | ||||
|   constexpr uint8_t RGB565                             = 7; | ||||
|   constexpr uint8_t PALETTED                           = 8; | ||||
|   constexpr uint8_t TEXT8X8                            = 9; | ||||
|   constexpr uint8_t TEXTVGA                            = 10; | ||||
|   constexpr uint8_t BARGRAPH                           = 11; | ||||
|  | ||||
|   constexpr uint8_t ALPHA_FUNC_NEVER                   = 0; | ||||
|   constexpr uint8_t ALPHA_FUNC_LESS                    = 1; | ||||
|   constexpr uint8_t ALPHA_FUNC_LEQUAL                  = 2; | ||||
|   constexpr uint8_t ALPHA_FUNC_GREATER                 = 3; | ||||
|   constexpr uint8_t ALPHA_FUNC_GEQUAL                  = 4; | ||||
|   constexpr uint8_t ALPHA_FUNC_EQUAL                   = 5; | ||||
|   constexpr uint8_t ALPHA_FUNC_NOTEQUAL                = 6; | ||||
|   constexpr uint8_t ALPHA_FUNC_ALWAYS                  = 7; | ||||
|  | ||||
|   constexpr uint8_t NEAREST                            = 0; | ||||
|   constexpr uint8_t BILINEAR                           = 1; | ||||
|   constexpr uint8_t BORDER                             = 0; | ||||
|   constexpr uint8_t REPEAT                             = 1; | ||||
|  | ||||
|   constexpr uint8_t BLEND_FUNC_ZERO                    = 0; | ||||
|   constexpr uint8_t BLEND_FUNC_ONE                     = 1; | ||||
|   constexpr uint8_t BLEND_FUNC_SRC_ALPHA               = 2; | ||||
|   constexpr uint8_t BLEND_FUNC_DST_ALPHA               = 3; | ||||
|   constexpr uint8_t BLEND_FUNC_ONE_MINUS_SRC_ALPHA     = 4; | ||||
|   constexpr uint8_t BLEND_FUNC_ONE_MINUS_DST_ALPHA     = 5; | ||||
|  | ||||
|   constexpr uint32_t COLOR_MASK_RED                    = 8; | ||||
|   constexpr uint32_t COLOR_MASK_GRN                    = 4; | ||||
|   constexpr uint32_t COLOR_MASK_BLU                    = 2; | ||||
|   constexpr uint32_t COLOR_MASK_ALPHA                  = 1; | ||||
|  | ||||
|   constexpr uint8_t STENCIL_FUNC_NEVER                 = 0; | ||||
|   constexpr uint8_t STENCIL_FUNC_LESS                  = 1; | ||||
|   constexpr uint8_t STENCIL_FUNC_LEQUAL                = 2; | ||||
|   constexpr uint8_t STENCIL_FUNC_GREATER               = 3; | ||||
|   constexpr uint8_t STENCIL_FUNC_GEQUAL                = 4; | ||||
|   constexpr uint8_t STENCIL_FUNC_EQUAL                 = 5; | ||||
|   constexpr uint8_t STENCIL_FUNC_NOTEQUAL              = 6; | ||||
|   constexpr uint8_t STENCIL_FUNC_ALWAYS                = 7; | ||||
|  | ||||
|   constexpr uint8_t STENCIL_OP_ZERO                    = 0; | ||||
|   constexpr uint8_t STENCIL_OP_KEEP                    = 1; | ||||
|   constexpr uint8_t STENCIL_OP_REPLACE                 = 2; | ||||
|   constexpr uint8_t STENCIL_OP_INCR                    = 3; | ||||
|   constexpr uint8_t STENCIL_OP_DECR                    = 4; | ||||
|   constexpr uint8_t STENCIL_OP_INVERT                  = 5; | ||||
|  | ||||
|   typedef enum: uint32_t { | ||||
|    BITMAPS                                             = 1, | ||||
|    POINTS                                              = 2, | ||||
|    LINES                                               = 3, | ||||
|    LINE_STRIP                                          = 4, | ||||
|    EDGE_STRIP_R                                        = 5, | ||||
|    EDGE_STRIP_L                                        = 6, | ||||
|    EDGE_STRIP_A                                        = 7, | ||||
|    EDGE_STRIP_B                                        = 8, | ||||
|    RECTS                                               = 9 | ||||
|   } begin_t; | ||||
| } | ||||
|  | ||||
| namespace FTDI_FT800_DL { | ||||
|   constexpr uint32_t ALPHA_FUNC                         = 0x09000000; | ||||
|   constexpr uint32_t BEGIN                              = 0x1F000000; | ||||
|   constexpr uint32_t BITMAP_HANDLE                      = 0x05000000; | ||||
|   constexpr uint32_t BITMAP_LAYOUT                      = 0x07000000; | ||||
|   constexpr uint32_t BITMAP_SIZE                        = 0x08000000; | ||||
|   constexpr uint32_t BITMAP_SOURCE                      = 0x01000000; | ||||
|   constexpr uint32_t BITMAP_TRANSFORM_A                 = 0x15000000; | ||||
|   constexpr uint32_t BITMAP_TRANSFORM_B                 = 0x16000000; | ||||
|   constexpr uint32_t BITMAP_TRANSFORM_C                 = 0x17000000; | ||||
|   constexpr uint32_t BITMAP_TRANSFORM_D                 = 0x18000000; | ||||
|   constexpr uint32_t BITMAP_TRANSFORM_E                 = 0x19000000; | ||||
|   constexpr uint32_t BITMAP_TRANSFORM_F                 = 0x1A000000; | ||||
|   constexpr uint32_t BLEND_FUNC                         = 0x0B000000; | ||||
|   constexpr uint32_t CALL                               = 0x1D000000; | ||||
|   constexpr uint32_t CELL                               = 0x06000000; | ||||
|   constexpr uint32_t CLEAR                              = 0x26000000; | ||||
|   constexpr uint32_t CLEAR_COLOR_BUFFER                 = 0x00000004; | ||||
|   constexpr uint32_t CLEAR_STENCIL_BUFFER               = 0x00000002; | ||||
|   constexpr uint32_t CLEAR_TAG_BUFFER                   = 0x00000001; | ||||
|   constexpr uint32_t CLEAR_COLOR_A                      = 0x0F000000; | ||||
|   constexpr uint32_t CLEAR_COLOR_RGB                    = 0x02000000; | ||||
|   constexpr uint32_t CLEAR_STENCIL                      = 0x11000000; | ||||
|   constexpr uint32_t CLEAR_TAG                          = 0x12000000; | ||||
|   constexpr uint32_t COLOR_A                            = 0x10000000; | ||||
|   constexpr uint32_t COLOR_MASK                         = 0x20000000; | ||||
|   constexpr uint32_t COLOR_RGB                          = 0x04000000; | ||||
|   constexpr uint32_t DL_DISPLAY                         = 0x00000000; | ||||
|   constexpr uint32_t END                                = 0x21000000; | ||||
|   constexpr uint32_t JUMP                               = 0x1E000000; | ||||
|   constexpr uint32_t LINE_WIDTH                         = 0x0E000000; | ||||
|   constexpr uint32_t MACRO                              = 0x25000000; | ||||
|   constexpr uint32_t POINT_SIZE                         = 0x0D000000; | ||||
|   constexpr uint32_t RESTORE_CONTEXT                    = 0x23000000; | ||||
|   constexpr uint32_t RETURN                             = 0x24000000; | ||||
|   constexpr uint32_t SAVE_CONTEXT                       = 0x22000000; | ||||
|   constexpr uint32_t SCISSOR_SIZE                       = 0x1C000000; | ||||
|   constexpr uint32_t SCISSOR_XY                         = 0x1B000000; | ||||
|   constexpr uint32_t STENCIL_FUNC                       = 0x0A000000; | ||||
|   constexpr uint32_t STENCIL_MASK                       = 0x13000000; | ||||
|   constexpr uint32_t STENCIL_OP                         = 0x0C000000; | ||||
|   constexpr uint32_t TAG                                = 0x03000000; | ||||
|   constexpr uint32_t TAG_MASK                           = 0x14000000; | ||||
|   constexpr uint32_t VERTEX2F                           = 0x40000000; | ||||
|   constexpr uint32_t VERTEX2II                          = 0x80000000; | ||||
| } | ||||
|  | ||||
| namespace FTDI_FT810_DL { | ||||
|   constexpr uint32_t NOP                                = 0x25000000; | ||||
|   constexpr uint32_t BITMAP_LAYOUT_H                    = 0x28000000; | ||||
|   constexpr uint32_t BITMAP_SIZE_H                      = 0x29000000; | ||||
|   constexpr uint32_t VERTEX_FORMAT                      = 0x27000000; | ||||
|   constexpr uint32_t VERTEX_TRANSLATE_X                 = 0x2B000000; | ||||
|   constexpr uint32_t VERTEX_TRANSLATE_Y                 = 0x2C000000; | ||||
| } | ||||
|  | ||||
| // CO-PROCESSOR ENGINE COMMANDS | ||||
| namespace FTDI { | ||||
|   constexpr uint32_t CMD_DLSTART                        = 0xFFFFFF00; | ||||
|   constexpr uint32_t CMD_SWAP                           = 0xFFFFFF01; | ||||
|   constexpr uint32_t CMD_COLDSTART                      = 0xFFFFFF32; | ||||
|   constexpr uint32_t CMD_INTERRUPT                      = 0xFFFFFF02; | ||||
|   constexpr uint32_t CMD_APPEND                         = 0xFFFFFF1E; | ||||
|   constexpr uint32_t CMD_REGREAD                        = 0xFFFFFF19; | ||||
|   constexpr uint32_t CMD_MEMWRITE                       = 0xFFFFFF1A; | ||||
|   constexpr uint32_t CMD_INFLATE                        = 0xFFFFFF22; | ||||
|   constexpr uint32_t CMD_LOADIMAGE                      = 0xFFFFFF24; | ||||
|   constexpr uint32_t CMD_MEMCRC                         = 0xFFFFFF18; | ||||
|   constexpr uint32_t CMD_MEMZERO                        = 0xFFFFFF1C; | ||||
|   constexpr uint32_t CMD_MEMSET                         = 0xFFFFFF1B; | ||||
|   constexpr uint32_t CMD_MEMCPY                         = 0xFFFFFF1D; | ||||
|   constexpr uint32_t CMD_BUTTON                         = 0xFFFFFF0D; | ||||
|   constexpr uint32_t CMD_CLOCK                          = 0xFFFFFF14; | ||||
|   constexpr uint32_t CMD_FGCOLOR                        = 0xFFFFFF0A; | ||||
|   constexpr uint32_t CMD_BGCOLOR                        = 0xFFFFFF09; | ||||
|   constexpr uint32_t CMD_GRADCOLOR                      = 0xFFFFFF34; | ||||
|   constexpr uint32_t CMD_GAUGE                          = 0xFFFFFF13; | ||||
|   constexpr uint32_t CMD_GRADIENT                       = 0xFFFFFF0B; | ||||
|   constexpr uint32_t CMD_KEYS                           = 0xFFFFFF0E; | ||||
|   constexpr uint32_t CMD_PROGRESS                       = 0xFFFFFF0F; | ||||
|   constexpr uint32_t CMD_SCROLLBAR                      = 0xFFFFFF11; | ||||
|   constexpr uint32_t CMD_SLIDER                         = 0xFFFFFF10; | ||||
|   constexpr uint32_t CMD_DIAL                           = 0xFFFFFF2D; | ||||
|   constexpr uint32_t CMD_TOGGLE                         = 0xFFFFFF12; | ||||
|   constexpr uint32_t CMD_TEXT                           = 0xFFFFFF0C; | ||||
|   constexpr uint32_t CMD_NUMBER                         = 0xFFFFFF2E; | ||||
|   constexpr uint32_t CMD_LOADIDENTITY                   = 0xFFFFFF26; | ||||
|   constexpr uint32_t CMD_SETMATRIX                      = 0xFFFFFF2A; | ||||
|   constexpr uint32_t CMD_GETMATRIX                      = 0xFFFFFF33; | ||||
|   constexpr uint32_t CMD_GETPTR                         = 0xFFFFFF23; | ||||
|   constexpr uint32_t CMD_GETPROPS                       = 0xFFFFFF25; | ||||
|   constexpr uint32_t CMD_SCALE                          = 0xFFFFFF28; | ||||
|   constexpr uint32_t CMD_ROTATE                         = 0xFFFFFF29; | ||||
|   constexpr uint32_t CMD_TRANSLATE                      = 0xFFFFFF27; | ||||
|   constexpr uint32_t CMD_CALIBRATE                      = 0xFFFFFF15; | ||||
|   constexpr uint32_t CMD_SPINNER                        = 0xFFFFFF16; | ||||
|   constexpr uint32_t CMD_SCREENSAVER                    = 0xFFFFFF2F; | ||||
|   constexpr uint32_t CMD_SKETCH                         = 0xFFFFFF30; | ||||
|   constexpr uint32_t CMD_STOP                           = 0xFFFFFF17; | ||||
|   constexpr uint32_t CMD_SETFONT                        = 0xFFFFFF2B; | ||||
|   constexpr uint32_t CMD_TRACK                          = 0xFFFFFF2C; | ||||
|   constexpr uint32_t CMD_SNAPSHOT                       = 0xFFFFFF1F; | ||||
|   constexpr uint32_t CMD_LOGO                           = 0xFFFFFF31; | ||||
| } | ||||
|  | ||||
| namespace FTDI_FT810 { | ||||
|   constexpr uint32_t CMD_SETROTATE                    = 0xFFFFFF36; | ||||
|   constexpr uint32_t CMD_SNAPSHOT2                    = 0xFFFFFF37; | ||||
|   constexpr uint32_t CMD_SETBASE                      = 0xFFFFFF38; | ||||
|   constexpr uint32_t CMD_MEDIAFIFO                    = 0xFFFFFF39; | ||||
|   constexpr uint32_t CMD_PLAYVIDEO                    = 0xFFFFFF3A; | ||||
|   constexpr uint32_t CMD_VIDEOSTART                   = 0xFFFFFF40; | ||||
|   constexpr uint32_t CMD_VIDEOFRAME                   = 0xFFFFFF41; | ||||
|   constexpr uint32_t CMD_SETBITMAP                    = 0xFFFFFF43; | ||||
| } | ||||
|  | ||||
| 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 | ||||
|   }; | ||||
|  | ||||
|   enum note_t { | ||||
|     END_SONG                                        = 0xFF, | ||||
|     REST                                            = 0x00, | ||||
|  | ||||
|     NOTE_C1                                         = 0x18, // 24 | ||||
|     NOTE_C1S                                        = 0x19, | ||||
|     NOTE_D1                                         = 0x1A, | ||||
|     NOTE_D1S                                        = 0x1B, | ||||
|     NOTE_E1                                         = 0x1C, | ||||
|     NOTE_F1                                         = 0x1D, | ||||
|     NOTE_F1S                                        = 0x1E, | ||||
|     NOTE_G1                                         = 0x1F, | ||||
|     NOTE_G1S                                        = 0x20, | ||||
|     NOTE_A1                                         = 0x21, | ||||
|     NOTE_A1S                                        = 0x22, | ||||
|     NOTE_B1                                         = 0x23, | ||||
|  | ||||
|     NOTE_C2                                         = 0x24,  //36 | ||||
|     NOTE_C2S                                        = 0x25, | ||||
|     NOTE_D2                                         = 0x26, | ||||
|     NOTE_D2S                                        = 0x27, | ||||
|     NOTE_E2                                         = 0x28, | ||||
|     NOTE_F2                                         = 0x29, | ||||
|     NOTE_F2S                                        = 0x2A, | ||||
|     NOTE_G2                                         = 0x2B, | ||||
|     NOTE_G2S                                        = 0x2C, | ||||
|     NOTE_A2                                         = 0x2D, | ||||
|     NOTE_A2S                                        = 0x2E, | ||||
|     NOTE_B2                                         = 0x2F, | ||||
|  | ||||
|     NOTE_C3                                         = 0x30, | ||||
|     NOTE_C3S                                        = 0x31, | ||||
|     NOTE_D3                                         = 0x32, | ||||
|     NOTE_D3S                                        = 0x33, | ||||
|     NOTE_E3                                         = 0x34, | ||||
|     NOTE_F3                                         = 0x35, | ||||
|     NOTE_F3S                                        = 0x36, | ||||
|     NOTE_G3                                         = 0x37, | ||||
|     NOTE_G3S                                        = 0x38, | ||||
|     NOTE_A3                                         = 0x39, | ||||
|     NOTE_A3S                                        = 0x3A, | ||||
|     NOTE_B3                                         = 0x3B, | ||||
|  | ||||
|     NOTE_C4                                         = 0x3C, | ||||
|     NOTE_C4S                                        = 0x3D, | ||||
|     NOTE_D4                                         = 0x3E, | ||||
|     NOTE_D4S                                        = 0x3F, | ||||
|     NOTE_E4                                         = 0x40, | ||||
|     NOTE_F4                                         = 0x41, | ||||
|     NOTE_F4S                                        = 0x42, | ||||
|     NOTE_G4                                         = 0x43, | ||||
|     NOTE_G4S                                        = 0x44, | ||||
|     NOTE_A4                                         = 0x45, | ||||
|     NOTE_A4S                                        = 0x46, | ||||
|     NOTE_B4                                         = 0x47, | ||||
|  | ||||
|     NOTE_C5                                         = 0x48, | ||||
|     NOTE_C5S                                        = 0x49, | ||||
|     NOTE_D5                                         = 0x4A, | ||||
|     NOTE_D5S                                        = 0x4B, | ||||
|     NOTE_E5                                         = 0x4C, | ||||
|     NOTE_F5                                         = 0x4D, | ||||
|     NOTE_F5S                                        = 0x4E, | ||||
|     NOTE_G5                                         = 0x4F, | ||||
|     NOTE_G5S                                        = 0x50, | ||||
|     NOTE_A5                                         = 0x51, | ||||
|     NOTE_A5S                                        = 0x52, | ||||
|     NOTE_B5                                         = 0x53, | ||||
|   }; | ||||
| } | ||||
| @@ -0,0 +1,118 @@ | ||||
| /****************** | ||||
|  * display_list.h * | ||||
|  *****************/ | ||||
|  | ||||
| /********************************************************************************** | ||||
|  * Adapted from:                                                                  * | ||||
|  *     https://github.com/RudolphRiedel/FT800-FT813                               * | ||||
|  *     By Rudolph Riedel                                                          * | ||||
|  *                                                                                * | ||||
|  * MIT License                                                                    * | ||||
|  *                                                                                * | ||||
|  * Copyright (c) 2017                                                             * | ||||
|  *                                                                                * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy   * | ||||
|  * of this software and associated documentation files (the "Software"), to deal  * | ||||
|  * in the Software without restriction, including without limitation the rights   * | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      * | ||||
|  * copies of the Software, and to permit persons to whom the Software is          * | ||||
|  * furnished to do so, subject to the following conditions:                       * | ||||
|  *                                                                                * | ||||
|  * The above copyright notice and this permission notice shall be included in all * | ||||
|  * copies or substantial portions of the Software.                                * | ||||
|  *                                                                                * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     * | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       * | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE    * | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         * | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  * | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  * | ||||
|  * SOFTWARE.                                                                      * | ||||
|  *                                                                                * | ||||
|  **********************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace FTDI { | ||||
|   /* FT8xx graphics engine specific macros useful for static display list generation */ | ||||
|   inline uint32_t ALPHA_FUNC(uint8_t func, uint8_t ref)        {return DL::ALPHA_FUNC|((func&7UL)<<8)|(ref&255UL);} | ||||
|   inline uint32_t BEGIN(begin_t prim)                          {return DL::BEGIN|(prim&15UL);} | ||||
|  | ||||
|   inline uint32_t BITMAP_SOURCE(uint32_t ram_g_addr)           {return DL::BITMAP_SOURCE|(ram_g_addr & (FTDI::ftdi_memory_map::RAM_G_SIZE-1));} | ||||
|   inline uint32_t BITMAP_HANDLE(uint8_t handle)                {return DL::BITMAP_HANDLE|(handle&31UL);} | ||||
|   inline uint32_t BITMAP_LAYOUT(uint8_t format, uint16_t linestride, uint16_t height) | ||||
|                                                                {return DL::BITMAP_LAYOUT|((format&31UL)<<19)|((linestride&1023UL)<<9)|(height&511UL);} | ||||
|  | ||||
|   inline uint32_t BITMAP_SIZE(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) | ||||
|                                                                {return DL::BITMAP_SIZE|((filter&1UL)<<20)|((wrapx&1UL)<<19)|((wrapy&1UL)<<18)|((width&511UL)<<9)|(height&511UL);} | ||||
|   #if FTDI_API_LEVEL >= 810 | ||||
|   inline uint32_t BITMAP_LAYOUT_H(uint8_t linestride, uint8_t height) | ||||
|                                                                {return DL::BITMAP_LAYOUT_H|((linestride&3UL)<<2)|(height&3UL);} | ||||
|   inline uint32_t BITMAP_SIZE_H(uint8_t width, uint8_t height) | ||||
|                                                                {return DL::BITMAP_SIZE_H|((width&3UL)<<2)|(height&3UL);} | ||||
|   #endif | ||||
|   inline uint32_t BITMAP_TRANSFORM_A(uint16_t a)               {return DL::BITMAP_TRANSFORM_A|(a&131071UL);} | ||||
|   inline uint32_t BITMAP_TRANSFORM_B(uint16_t b)               {return DL::BITMAP_TRANSFORM_B|(b&131071UL);} | ||||
|   inline uint32_t BITMAP_TRANSFORM_C(uint32_t c)               {return DL::BITMAP_TRANSFORM_C|(c&16777215UL);} | ||||
|   inline uint32_t BITMAP_TRANSFORM_D(uint16_t d)               {return DL::BITMAP_TRANSFORM_D|(d&131071UL);} | ||||
|   inline uint32_t BITMAP_TRANSFORM_E(uint16_t e)               {return DL::BITMAP_TRANSFORM_E|(e&131071UL);} | ||||
|   inline uint32_t BITMAP_TRANSFORM_F(uint32_t f)               {return DL::BITMAP_TRANSFORM_F|(f&16777215UL);} | ||||
|   inline uint32_t BLEND_FUNC(uint8_t src,uint8_t dst)          {return DL::BLEND_FUNC|((src&7UL)<<3)|(dst&7UL);} | ||||
|   inline uint32_t CALL(uint16_t dest)                          {return DL::CALL|(dest&65535UL);} | ||||
|   inline uint32_t CELL(uint8_t cell)                           {return DL::CELL|(cell&127UL);} | ||||
|   inline uint32_t CLEAR(bool c,bool s,bool t)                  {return DL::CLEAR|((c?1UL:0UL)<<2)|((s?1UL:0UL)<<1)|(t?1UL:0UL);} | ||||
|   inline uint32_t CLEAR_COLOR_A(uint8_t alpha)                 {return DL::CLEAR_COLOR_A|(alpha&255UL);} | ||||
|   inline uint32_t CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) | ||||
|                                                                {return DL::CLEAR_COLOR_RGB|((red&255UL)<<16)|((green&255UL)<<8)|(blue&255UL);} | ||||
|   inline uint32_t CLEAR_COLOR_RGB(uint32_t rgb)                {return DL::CLEAR_COLOR_RGB|rgb;} | ||||
|   inline uint32_t CLEAR_STENCIL(uint8_t s)                     {return DL::CLEAR_STENCIL|(s&255UL);} | ||||
|   inline uint32_t CLEAR_TAG(uint8_t s)                         {return DL::CLEAR_TAG|(s&255UL);} | ||||
|   inline uint32_t COLOR_A(uint8_t alpha)                       {return DL::COLOR_A|(alpha&255UL);} | ||||
|   inline uint32_t COLOR_MASK(bool r, bool g, bool b, bool a)   {return DL::COLOR_MASK|((r?1UL:0UL)<<3)|((g?1UL:0UL)<<2)|((b?1UL:0UL)<<1)|(a?1UL:0UL);} | ||||
|   inline uint32_t COLOR_RGB(uint8_t red,uint8_t green,uint8_t blue) | ||||
|                                                                {return DL::COLOR_RGB|((red&255UL)<<16)|((green&255UL)<<8)|(blue&255UL);} | ||||
|   inline uint32_t COLOR_RGB(uint32_t rgb)                      {return DL::COLOR_RGB|rgb;} | ||||
|   /* inline uint32_t DISPLAY()                                 {return (0UL<<24)) */ | ||||
|   inline uint32_t END()                                        {return DL::END;} | ||||
|   inline uint32_t JUMP(uint16_t dest)                          {return DL::JUMP|(dest&65535UL);} | ||||
|   inline uint32_t LINE_WIDTH(uint16_t width)                   {return DL::LINE_WIDTH|(width&4095UL);} | ||||
|   inline uint32_t MACRO(uint8_t m)                             {return DL::MACRO|(m&1UL);} | ||||
|   inline uint32_t POINT_SIZE(uint16_t size)                    {return DL::POINT_SIZE|(size&8191UL);} | ||||
|   inline uint32_t RESTORE_CONTEXT()                            {return DL::RESTORE_CONTEXT;} | ||||
|   inline uint32_t RETURN ()                                    {return DL::RETURN;} | ||||
|   inline uint32_t SAVE_CONTEXT()                               {return DL::SAVE_CONTEXT;} | ||||
|   inline uint32_t SCISSOR_XY(uint16_t x,uint16_t y) { | ||||
|     return DL::SCISSOR_XY | | ||||
|       (FTDI::ftdi_chip >= 810 | ||||
|         ? ((x&2047UL)<<11)|(y&2047UL) | ||||
|         : ((x& 511UL)<<10)|(y&511UL)); | ||||
|   } | ||||
|   inline uint32_t SCISSOR_SIZE(uint16_t w,uint16_t h) { | ||||
|     return DL::SCISSOR_SIZE | | ||||
|       (FTDI::ftdi_chip >= 810 | ||||
|         ? ((w&4095UL)<<12)|(h&4095UL) | ||||
|         : ((w&1023UL)<<10)|(h&1023UL)); | ||||
|   } | ||||
|   inline uint32_t SCISSOR_XY()                                 {return DL::SCISSOR_XY;} | ||||
|   inline uint32_t SCISSOR_SIZE() { | ||||
|     return DL::SCISSOR_SIZE | | ||||
|       (FTDI::ftdi_chip >= 810 | ||||
|         ? (2048UL<<12)|(2048UL) | ||||
|         : ( 512UL<<10)|( 512UL)); | ||||
|   } | ||||
|   inline uint32_t STENCIL_FUNC(uint16_t func, uint8_t ref, uint8_t mask) | ||||
|                                                                {return DL::STENCIL_FUNC|((func&7UL)<<16)|((ref&255UL)<<8)|(mask&255UL);} | ||||
|   inline uint32_t STENCIL_MASK(uint8_t mask)                   {return DL::STENCIL_MASK|(mask&255UL);} | ||||
|   inline uint32_t STENCIL_OP(uint8_t sfail, uint8_t spass)     {return DL::STENCIL_OP|(((sfail)&7UL)<<3)|(spass&7UL);} | ||||
|   inline uint32_t TAG(uint8_t s)                               {return DL::TAG|(s&255UL);} | ||||
|   inline uint32_t TAG_MASK(bool mask)                          {return DL::TAG_MASK|(mask?1:0);} | ||||
|   inline uint32_t VERTEX2F(uint16_t x, uint16_t y)             {return DL::VERTEX2F|((x&32767UL)<<15)|(y&32767UL);} | ||||
|   inline uint32_t VERTEX2II(uint16_t x,uint16_t y, uint8_t handle = 0, uint8_t cell = 0) | ||||
|                                                                {return DL::VERTEX2II|((x&511UL)<<21)|((y&511UL)<<12)|((handle&31UL)<<7)|(cell&127UL);} | ||||
|  | ||||
|   #if FTDI_API_LEVEL >= 810 | ||||
|   inline uint32_t VERTEX_FORMAT(uint8_t frac)                  {return DL::VERTEX_FORMAT|(frac&7UL);} | ||||
|   inline uint32_t VERTEX_TRANSLATE_X(int32_t x)                {return DL::VERTEX_TRANSLATE_X|(x&131071UL);} | ||||
|   inline uint32_t VERTEX_TRANSLATE_Y(int32_t y)                {return DL::VERTEX_TRANSLATE_Y|(y&131071UL);} | ||||
|   #endif | ||||
| } | ||||
| @@ -0,0 +1,40 @@ | ||||
| /**************** | ||||
|  * ftdi_basic.h * | ||||
|  ****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2019 - Aleph Objects, Inc.                  * | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../compat.h" | ||||
|  | ||||
| #if !defined(__MARLIN_FIRMWARE__) | ||||
|   #define FTDI_BASIC | ||||
| #endif | ||||
|  | ||||
| #ifdef FTDI_BASIC | ||||
|   #include "registers_ft800.h" | ||||
|   #include "registers_ft810.h" | ||||
|   #include "constants.h" | ||||
|   #include "boards.h" | ||||
|   #include "commands.h" | ||||
|   #include "spi.h" | ||||
|   #include "display_list.h" | ||||
|   #include "resolutions.h" | ||||
| #endif | ||||
| @@ -0,0 +1,150 @@ | ||||
| /********************* | ||||
|  * registers_ft800.h * | ||||
|  *********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * This header defines registers for the FTDI FT800 LCD Driver chip.        * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| /******************************************************************************* | ||||
|  * FT810                                                                       * | ||||
|  *                                                                             * | ||||
|  * START    END ADDR   SIZE    NAME           DESCRIPTION                      * | ||||
|  *                                                                             * | ||||
|  * 0x000000 0x03FFFF   256 kB  RAM_G          Main Graphics RAM                * | ||||
|  *                                                                             * | ||||
|  * 0x0C0000 0x0C0003     4  B  ROM_CHIPID     [0:1] 0x800   Chip Id            * | ||||
|  *                                            [1:2] 0x0100  Vers ID            * | ||||
|  *                                                                             * | ||||
|  * 0x0BB23C 0x0FFFFB   275 kB  ROM_FONT       Font table and bitmap            * | ||||
|  *                                                                             * | ||||
|  * 0x0FFFFC 0x0FFFFF     4  B  ROM_FONT_ADDR  Font table pointer address       * | ||||
|  *                                                                             * | ||||
|  * 0x100000 0x101FFF     8 kB  RAM_DL         Display List RAM                 * | ||||
|  *                                                                             * | ||||
|  * 0x102000 0x1023FF     1 kB  RAM_PAL        Palette RAM                      * | ||||
|  *                                                                             * | ||||
|  * 0x102400 0x10257F   380  B  *          Registers                        * | ||||
|  *                                                                             * | ||||
|  * 0x108000 0x108FFF     4 kB  RAM_CMD        Command Buffer                   * | ||||
|  *                                                                             * | ||||
|  *******************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace FTDI { | ||||
|   struct ft800_memory_map { | ||||
|  | ||||
|     //         MEMORY LOCATIONS     FT800 | ||||
|     static constexpr uint32_t RAM_G          = 0x000000;   // Main Graphics RAM | ||||
|     static constexpr uint32_t ROM_CHIPID     = 0x0C0000;   // Chip ID/Version ID | ||||
|     static constexpr uint32_t ROM_FONT       = 0x0BB23C;   // Font ROM | ||||
|     static constexpr uint32_t ROM_FONT_ADDR  = 0x0FFFFC;   // Font Table Pointer | ||||
|     static constexpr uint32_t RAM_DL         = 0x100000;   // Display List RAM | ||||
|     static constexpr uint32_t RAM_PAL        = 0x102000;   // Palette RAM | ||||
|     static constexpr uint32_t RAM_REG        = 0x102400;   // Registers | ||||
|     static constexpr uint32_t RAM_CMD        = 0x108000;   // Command Buffer | ||||
|  | ||||
|     static constexpr uint32_t RAM_G_SIZE     = 256*1024l;  // 256k | ||||
|   }; | ||||
|  | ||||
|   struct ft800_registers { | ||||
|     // REGISTERS AND ADDRESSES    FT800 | ||||
|  | ||||
|     //             REGISTER              ADDRESS       SIZE    RESET VALUE     TYPE     DESCRIPTION | ||||
|  | ||||
|     static constexpr uint32_t ID                = 0x102400;  //    8    0x7C               r     Identification Register, Always 0x7C | ||||
|     static constexpr uint32_t FRAMES            = 0x102404;  //   32    0x00000000         r     Frame Counter, Since Reset | ||||
|     static constexpr uint32_t CLOCK             = 0x102408;  //   32    0x00000000         r     Clock cycles, Since Reset | ||||
|     static constexpr uint32_t FREQUENCY         = 0x10240C;  //   28    0x03938700       r/w     Main Clock Frequency | ||||
|     static constexpr uint32_t RENDERMODE        = 0x102410;  //    1    0x00             r/w     Rendering Mode: 0 = normal, 1 = single-line | ||||
|     static constexpr uint32_t SNAPY             = 0x102414;  //   11    0x0000           r/w     Scan Line Select for RENDERMODE 1 | ||||
|     static constexpr uint32_t SNAPSHOT          = 0x102418;  //    1    -                  r     Trigger for RENDERMODE 1 | ||||
|     static constexpr uint32_t CPURESET          = 0x10241C;  //    3    0x02             r/w     RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics | ||||
|     static constexpr uint32_t TAP_CRC           = 0x102420;  //   32    -                  r     Live Video Tap | ||||
|     static constexpr uint32_t TAP_MASK          = 0x102424;  //   32    0xFFFFFFFF       r/w     Live Video Tap Mask | ||||
|     static constexpr uint32_t HCYCLE            = 0x102428;  //   12    0x224            r/w     Horizontal Total Cycle Count | ||||
|     static constexpr uint32_t HOFFSET           = 0x10242C;  //   12    0x02B            r/w     Horizontal Display Start Offset | ||||
|     static constexpr uint32_t HSIZE             = 0x102430;  //   12    0x1E0            r/w     Horizontal Display Pixel Count | ||||
|     static constexpr uint32_t HSYNC0            = 0x102434;  //   12    0x000            r/w     Horizontal Sync Fall Offset | ||||
|     static constexpr uint32_t HSYNC1            = 0x102438;  //   12    0x029            r/w     Horizontal Sync Rise Offset | ||||
|     static constexpr uint32_t VCYCLE            = 0x10243C;  //   12    0x124            r/w     Vertical Total Cycle Count | ||||
|     static constexpr uint32_t VOFFSET           = 0x102440;  //   12    0x00C            r/w     Vertical Display Start Offset | ||||
|     static constexpr uint32_t VSIZE             = 0x102444;  //   12    0x110            r/w     Vertical Display Line Count | ||||
|     static constexpr uint32_t VSYNC0            = 0x102448;  //   10    0x000            r/w     Vertical Sync Fall Offset | ||||
|     static constexpr uint32_t VSYNC1            = 0x10244C;  //   10    0x00A            r/w     Vertical Sync Rise Offset | ||||
|     static constexpr uint32_t DLSWAP            = 0x102450;  //    2    0x00             r/w     Display List Swap Control | ||||
|     static constexpr uint32_t ROTATE            = 0x102454;  //    3    0x00             r/w     Screen 90,180, 270 degree rotate | ||||
|     static constexpr uint32_t OUTBITS           = 0x102458;  //    9    0x1B6            r/w     Output Resolution, 3x3x3 Bits | ||||
|     static constexpr uint32_t DITHER            = 0x10245C;  //    1    0x01             r/w     Output Dither Enable | ||||
|     static constexpr uint32_t SWIZZLE           = 0x102460;  //    4    0x00             r/w     Output RGB Swizzle, Pin Change for PCB Routing | ||||
|     static constexpr uint32_t CSPREAD           = 0x102464;  //    1    0x01             r/w     Output Clock Spreading Enable | ||||
|     static constexpr uint32_t PCLK_POL          = 0x102468;  //    1    0x00             r/w     PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge | ||||
|     static constexpr uint32_t PCLK              = 0x10246C;  //    8    0x00             r/w     PCLK Frequency Divider, 0 = Disable Clock | ||||
|     static constexpr uint32_t TAG_X             = 0x102470;  //   11    0x000            r/w     Tag Query X Coordinate | ||||
|     static constexpr uint32_t TAG_Y             = 0x102474;  //   11    0x000            r/w     Tag Query Y Coordinate | ||||
|     static constexpr uint32_t TAG               = 0x102478;  //    8    0x00               r     Tag Query Result | ||||
|     static constexpr uint32_t VOL_PB            = 0x10247C;  //    8    0xFF             r/w     Audio Playback Volume | ||||
|     static constexpr uint32_t VOL_SOUND         = 0x102480;  //    8    0xFF             r/w     Audio Synthesizer Volume | ||||
|     static constexpr uint32_t SOUND             = 0x102484;  //   16    0x0000           r/w     Audio Sound Effect Select | ||||
|     static constexpr uint32_t PLAY              = 0x102488;  //    1    0x00             r/w     Audio Start Effect Playback | ||||
|     static constexpr uint32_t GPIO_DIR          = 0x10248C;  //    8    0x80             r/w     GPIO Pin Direction: 0 = Input , 1 = Output | ||||
|     static constexpr uint32_t GPIO              = 0x102490;  //    8    0x00             r/w     GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6 | ||||
|     static constexpr uint32_t INT_FLAGS         = 0x102498;  //    8    0x00               r     Interrupt Flags, Clear by Reading | ||||
|     static constexpr uint32_t INT_EN            = 0x10249C;  //    1    0x00             r/w     Global Interrupt Enable | ||||
|     static constexpr uint32_t INT_MASK          = 0x1024A0;  //    8    0xFF             r/w     Interrupt Enable Mask | ||||
|     static constexpr uint32_t PLAYBACK_START    = 0x1024A4;  //   20    0x00000          r/w     Audio Playback RAM Start Address | ||||
|     static constexpr uint32_t PLAYBACK_LENGTH   = 0x1024A8;  //   20    0x00000          r/w     Audio Playback Sample Length (Bytes) | ||||
|     static constexpr uint32_t PLAYBACK_READPTR  = 0x1024AC;  //   20    -                  r     Audio Playback Read Pointer | ||||
|     static constexpr uint32_t PLAYBACK_FREQ     = 0x1024B0;  //   16    0x1F40           r/w     Audio Playback Frequency (Hz) | ||||
|     static constexpr uint32_t PLAYBACK_FORMAT   = 0x1024B4;  //    2    0x00             r/w     Audio Playback Format | ||||
|     static constexpr uint32_t PLAYBACK_LOOP     = 0x1024B8;  //    1    0x00             r/w     Audio Playback Loop Enable | ||||
|     static constexpr uint32_t PLAYBACK_PLAY     = 0x1024BC;  //    1    0x00               r     Audio Start Playback | ||||
|     static constexpr uint32_t PWM_HZ            = 0x1024C0;  //   14    0x00FA           r/w     Backlight PWM Frequency (Hz) | ||||
|     static constexpr uint32_t PWM_DUTY          = 0x1024C4;  //    8    0x80             r/w     Backlight PWM Duty Cycle: 0 = 0%, 128 = 100% | ||||
|     static constexpr uint32_t MACRO_0           = 0x1024C8;  //   32    0x00000000       r/w     Display List Macro Command 0 | ||||
|     static constexpr uint32_t MACRO_1           = 0x1024CC;  //   32    0x00000000       r/w     Display List Macro Command 1 | ||||
|     static constexpr uint32_t CMD_READ          = 0x1024E4;  //   12    0x000            r/w     Command Buffer Read Pointer | ||||
|     static constexpr uint32_t CMD_WRITE         = 0x1024E8;  //   12    0x000            r/w     Command Buffer Write Pointer | ||||
|     static constexpr uint32_t CMD_DL            = 0x1024EC;  //   13    0x0000           r/w     Command Display List Offset | ||||
|     static constexpr uint32_t TOUCH_MODE        = 0x1024F0;  //    2    0x03             r/w     Touch-Screen Sampling Mode | ||||
|     static constexpr uint32_t TOUCH_ADC_MODE    = 0x1024F4;  //    1    0x01             r/w     Select Single Ended or Differential Sampling | ||||
|     static constexpr uint32_t TOUCH_CHARGE      = 0x1024F8;  //   16    0x1770           r/w     Touch Screen Charge Time, n x 6 Clocks | ||||
|     static constexpr uint32_t TOUCH_SETTLE      = 0x1024FC;  //    4    0x03             r/w     Touch-Screen Settle Time, n x 6 Clocks | ||||
|     static constexpr uint32_t TOUCH_OVERSAMPLE  = 0x102500;  //    4    0x07             r/w     Touch-Screen Oversample Factor | ||||
|     static constexpr uint32_t TOUCH_RZTHRESH    = 0x102504;  //   16    0xFFFF           r/w     Touch-Screen Resistance Threshold | ||||
|     static constexpr uint32_t TOUCH_RAW_XY      = 0x102508;  //   32    -                  r     Touch-Screen Raw (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_RZ          = 0x10250C;  //   16    -                  r     Touch-Screen Resistance | ||||
|     static constexpr uint32_t TOUCH_SCREEN_XY   = 0x102510;  //   32    -                  r     Touch-Screen Screen (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_TAG_XY      = 0x102514;  //   32    -                  r     Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_TAG         = 0x102518;  //    8    -                  r     Touch-Screen Tag 0 Result | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_A = 0x10251C;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient A (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_B = 0x102520;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient B (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_C = 0x102524;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient C (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_D = 0x102528;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient D (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_E = 0x10252C;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient E (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_F = 0x102530;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient F (s15.16) | ||||
|   //               Reserved Addresses      0x102434 - 0x102470 | ||||
|     static constexpr uint32_t TOUCH_DIRECT_XY   = 0x102574;  //   32    -                  r     Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_DIRECT_Z1Z2 = 0x102578;  //   32    -                  r     Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16) | ||||
|     static constexpr uint32_t TRACKER           = 0x109000;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8) | ||||
|   }; | ||||
| } | ||||
| @@ -0,0 +1,185 @@ | ||||
| /********************* | ||||
|  * registers_ft810.h * | ||||
|  *********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * This header defines registers for the FTDI FT810 LCD Driver chip.        * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| /******************************************************************************* | ||||
|  * FT810                                                                       * | ||||
|  *                                                                             * | ||||
|  * START    END ADDR   SIZE    NAME           DESCRIPTION                      * | ||||
|  *                                                                             * | ||||
|  * 0x000000 0x0FFFFF  1024 kB  RAM_G          Main Graphics RAM (0 to 1048572) * | ||||
|  *                                                                             * | ||||
|  * 0x0C0000 0x0C0003     4  B  ROM_CHIPID     [0:1] 0x800   Chip Id            * | ||||
|  *                                            [1:2] 0x0100  Vers 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  *          Registers                        * | ||||
|  *                                                                             * | ||||
|  * 0x308000 0x308FFF     4 kB  RAM_CMD        Command Buffer                   * | ||||
|  *                                                                             * | ||||
|  *******************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace FTDI { | ||||
|   struct ft810_memory_map { | ||||
|     //         MEMORY LOCATIONS     FT810 | ||||
|     static constexpr uint32_t RAM_G          = 0x000000;   // Main Graphics RAM | ||||
|     static constexpr uint32_t ROM_CHIPID     = 0x0C0000;   // Chip ID/Version ID | ||||
|     static constexpr uint32_t ROM_FONT       = 0x1E0000;   // Font ROM | ||||
|     static constexpr uint32_t ROM_FONT_ADDR  = 0x2FFFFC;   // Font Table Pointer | ||||
|     static constexpr uint32_t RAM_DL         = 0x300000;   // Display List RAM | ||||
|     static constexpr uint32_t RAM_REG        = 0x302000;   // Registers | ||||
|     static constexpr uint32_t RAM_CMD        = 0x308000;   // Command Buffer | ||||
|  | ||||
|     static constexpr uint32_t RAM_G_SIZE     = 1024*1024l; // 1024k | ||||
|   }; | ||||
|  | ||||
|   struct ft810_registers { | ||||
|     // REGISTERS AND ADDRESSES    FT810 | ||||
|  | ||||
|     //             REGISTER              ADDRESS       SIZE    RESET VALUE     TYPE     DESCRIPTION | ||||
|  | ||||
|     static constexpr uint32_t ID                = 0x302000;  //    8    0x7C               r     Identification Register, Always 0x7C | ||||
|     static constexpr uint32_t FRAMES            = 0x302004;  //   32    0x00000000         r     Frame Counter, Since Reset | ||||
|     static constexpr uint32_t CLOCK             = 0x302008;  //   32    0x00000000         r     Clock cycles, Since Reset | ||||
|     static constexpr uint32_t FREQUENCY         = 0x30200C;  //   28    0x03938700       r/w     Main Clock Frequency | ||||
|     static constexpr uint32_t RENDERMODE        = 0x302010;  //    1    0x00             r/w     Rendering Mode: 0 = normal, 1 = single-line | ||||
|     static constexpr uint32_t SNAPY             = 0x302014;  //   11    0x0000           r/w     Scan Line Select for RENDERMODE 1 | ||||
|     static constexpr uint32_t SNAPSHOT          = 0x302018;  //    1    -                  r     Trigger for RENDERMODE 1 | ||||
|     static constexpr uint32_t SNAPFORMAT        = 0x30201C;  //    6    0x20             r/w     Pixel Format for Scanline Readout | ||||
|     static constexpr uint32_t CPURESET          = 0x302020;  //    3    0x02             r/w     RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics | ||||
|     static constexpr uint32_t TAP_CRC           = 0x302024;  //   32    -                  r     Live Video Tap | ||||
|     static constexpr uint32_t TAP_MASK          = 0x302028;  //   32    0xFFFFFFFF       r/w     Live Video Tap Mask | ||||
|     static constexpr uint32_t HCYCLE            = 0x30202C;  //   12    0x224            r/w     Horizontal Total Cycle Count | ||||
|     static constexpr uint32_t HOFFSET           = 0x302030;  //   12    0x02B            r/w     Horizontal Display Start Offset | ||||
|     static constexpr uint32_t HSIZE             = 0x302034;  //   12    0x1E0            r/w     Horizontal Display Pixel Count | ||||
|     static constexpr uint32_t HSYNC0            = 0x302038;  //   12    0x000            r/w     Horizontal Sync Fall Offset | ||||
|     static constexpr uint32_t HSYNC1            = 0x30203C;  //   12    0x029            r/w     Horizontal Sync Rise Offset | ||||
|     static constexpr uint32_t VCYCLE            = 0x302040;  //   12    0x124            r/w     Vertical Total Cycle Count | ||||
|     static constexpr uint32_t VOFFSET           = 0x302044;  //   12    0x00C            r/w     Vertical Display Start Offset | ||||
|     static constexpr uint32_t VSIZE             = 0x302048;  //   12    0x110            r/w     Vertical Display Line Count | ||||
|     static constexpr uint32_t VSYNC0            = 0x30204C;  //   10    0x000            r/w     Vertical Sync Fall Offset | ||||
|     static constexpr uint32_t VSYNC1            = 0x302050;  //   10    0x00A            r/w     Vertical Sync Rise Offset | ||||
|     static constexpr uint32_t DLSWAP            = 0x302054;  //    2    0x00             r/w     Display List Swap Control | ||||
|     static constexpr uint32_t ROTATE            = 0x302058;  //    3    0x00             r/w     Screen 90,180, 270 degree rotate | ||||
|     static constexpr uint32_t OUTBITS           = 0x30205C;  //    9    0x1B6            r/w     Output Resolution, 3x3x3 Bits | ||||
|     static constexpr uint32_t DITHER            = 0x302060;  //    1    0x01             r/w     Output Dither Enable | ||||
|     static constexpr uint32_t SWIZZLE           = 0x302064;  //    4    0x00             r/w     Output RGB Swizzle, Pin Change for PCB Routing | ||||
|     static constexpr uint32_t CSPREAD           = 0x302068;  //    1    0x01             r/w     Output Clock Spreading Enable | ||||
|     static constexpr uint32_t PCLK_POL          = 0x30206C;  //    1    0x00             r/w     PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge | ||||
|     static constexpr uint32_t PCLK              = 0x302070;  //    8    0x00             r/w     PCLK Frequency Divider, 0 = Disable Clock | ||||
|     static constexpr uint32_t TAG_X             = 0x302074;  //   11    0x000            r/w     Tag Query X Coordinate | ||||
|     static constexpr uint32_t TAG_Y             = 0x302078;  //   11    0x000            r/w     Tag Query Y Coordinate | ||||
|     static constexpr uint32_t TAG               = 0x30207C;  //    8    0x00               r     Tag Query Result | ||||
|     static constexpr uint32_t VOL_PB            = 0x302080;  //    8    0xFF             r/w     Audio Playback Volume | ||||
|     static constexpr uint32_t VOL_SOUND         = 0x302084;  //    8    0xFF             r/w     Audio Synthesizer Volume | ||||
|     static constexpr uint32_t SOUND             = 0x302088;  //   16    0x0000           r/w     Audio Sound Effect Select | ||||
|     static constexpr uint32_t PLAY              = 0x30208C;  //    1    0x00             r/w     Audio Start Effect Playback | ||||
|     static constexpr uint32_t GPIO_DIR          = 0x302090;  //    8    0x80             r/w     GPIO Pin Direction: 0 = Input , 1 = Output | ||||
|     static constexpr uint32_t GPIO              = 0x302094;  //    8    0x00             r/w     GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6 | ||||
|     static constexpr uint32_t GPIOX_DIR         = 0x302098;  //   16    0x8000           r/w     Extended GPIO Pin Direction | ||||
|     static constexpr uint32_t GPIOX             = 0x30209C;  //   16    0x0080           r/w     Extended GPIO Pin Values | ||||
|     //             Reserved Addr           0x3020A0 | ||||
|     //             Reserved Addr           0x3020A4 | ||||
|     static constexpr uint32_t INT_FLAGS         = 0x3020A8;  //    8    0x00               r     Interrupt Flags, Clear by Reading | ||||
|     static constexpr uint32_t INT_EN            = 0x3020AC;  //    1    0x00             r/w     Global Interrupt Enable | ||||
|     static constexpr uint32_t INT_MASK          = 0x3020B0;  //    8    0xFF             r/w     Interrupt Enable Mask | ||||
|     static constexpr uint32_t PLAYBACK_START    = 0x3020B4;  //   20    0x00000          r/w     Audio Playback RAM Start Address | ||||
|     static constexpr uint32_t PLAYBACK_LENGTH   = 0x3020B8;  //   20    0x00000          r/w     Audio Playback Sample Length (Bytes) | ||||
|     static constexpr uint32_t PLAYBACK_READPTR  = 0x3020BC;  //   20    -                  r     Audio Playback Read Pointer | ||||
|     static constexpr uint32_t PLAYBACK_FREQ     = 0x3020C0;  //   16    0x1F40           r/w     Audio Playback Frequency (Hz) | ||||
|     static constexpr uint32_t PLAYBACK_FORMAT   = 0x3020C4;  //    2    0x00             r/w     Audio Playback Format | ||||
|     static constexpr uint32_t PLAYBACK_LOOP     = 0x3020C8;  //    1    0x00             r/w     Audio Playback Loop Enable | ||||
|     static constexpr uint32_t PLAYBACK_PLAY     = 0x3020CC;  //    1    0x00               r     Audio Start Playback | ||||
|     static constexpr uint32_t PWM_HZ            = 0x3020D0;  //   14    0x00FA           r/w     Backlight PWM Frequency (Hz) | ||||
|     static constexpr uint32_t PWM_DUTY          = 0x3020D4;  //    8    0x80             r/w     Backlight PWM Duty Cycle: 0 = 0%, 128 = 100% | ||||
|     static constexpr uint32_t MACRO_0           = 0x3020D8;  //   32    0x00000000       r/w     Display List Macro Command 0 | ||||
|     static constexpr uint32_t 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 | ||||
|     static constexpr uint32_t CMD_READ          = 0x3020F8;  //   12    0x000            r/w     Command Buffer Read Pointer | ||||
|     static constexpr uint32_t CMD_WRITE         = 0x3020FC;  //   12    0x000            r/w     Command Buffer Write Pointer | ||||
|     static constexpr uint32_t CMD_DL            = 0x302100;  //   13    0x0000           r/w     Command Display List Offset | ||||
|     static constexpr uint32_t TOUCH_MODE        = 0x302104;  //    2    0x03             r/w     Touch-Screen Sampling Mode | ||||
|     static constexpr uint32_t TOUCH_ADC_MODE    = 0x302108;  //    1    0x01             r/w     Select Single Ended or Differential Sampling | ||||
|     static constexpr uint32_t TOUCH_CHARGE      = 0x30210C;  //   16    0x1770           r/w     Touch Screen Charge Time, n x 6 Clocks | ||||
|     static constexpr uint32_t TOUCH_SETTLE      = 0x302110;  //    4    0x03             r/w     Touch-Screen Settle Time, n x 6 Clocks | ||||
|     static constexpr uint32_t TOUCH_OVERSAMPLE  = 0x302114;  //    4    0x07             r/w     Touch-Screen Oversample Factor | ||||
|     static constexpr uint32_t TOUCH_RZTHRESH    = 0x302118;  //   16    0xFFFF           r/w     Touch-Screen Resistance Threshold | ||||
|     static constexpr uint32_t TOUCH_RAW_XY      = 0x30211C;  //   32    -                  r     Touch-Screen Raw (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_RZ          = 0x302120;  //   16    -                  r     Touch-Screen Resistance | ||||
|     static constexpr uint32_t TOUCH_SCREEN_XY   = 0x302124;  //   32    -                  r     Touch-Screen Screen (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_TAG_XY      = 0x302128;  //   32    -                  r     Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_TAG         = 0x30212C;  //    8    -                  r     Touch-Screen Tag 0 Result | ||||
|     static constexpr uint32_t TOUCH_TAG1_XY     = 0x302130;  //   32    -                  r     Touch-Screen Tag 1 Lookup | ||||
|     static constexpr uint32_t TOUCH_TAG1        = 0x302134;  //    8    -                  r     Touch-Screen Tag 1 Result | ||||
|     static constexpr uint32_t TOUCH_TAG2_XY     = 0x302138;  //   32    -                  r     Touch-Screen Tag 2 Lookup | ||||
|     static constexpr uint32_t TOUCH_TAG2        = 0x30213C;  //    8    -                  r     Touch-Screen Tag 2 Result | ||||
|     static constexpr uint32_t TOUCH_TAG3_XY     = 0x302140;  //   32    -                  r     Touch-Screen Tag 3 Lookup | ||||
|     static constexpr uint32_t TOUCH_TAG3        = 0x302144;  //    8    -                  r     Touch-Screen Tag 3 Result | ||||
|     static constexpr uint32_t TOUCH_TAG4_XY     = 0x302148;  //   32    -                  r     Touch-Screen Tag 4 Lookup | ||||
|     static constexpr uint32_t TOUCH_TAG4        = 0x30214C;  //    8    -                  r     Touch-Screen Tag 4 Result | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_A = 0x302150;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient A (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_B = 0x302154;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient B (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_C = 0x302158;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient C (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_D = 0x30215C;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient D (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_E = 0x302160;  //   32    0x00010000       r/w     Touch-Screen Transform Coefficient E (s15.16) | ||||
|     static constexpr uint32_t TOUCH_TRANSFORM_F = 0x302164;  //   32    0x00000000       r/w     Touch-Screen Transform Coefficient F (s15.16) | ||||
|     static constexpr uint32_t TOUCH_CONFIG      = 0x302168;  //   16    0x8381           r/w     Touch Configuration | ||||
|     static constexpr uint32_t CTOUCH_TOUCH4_X   = 0x30216C;  //   16    -                  r     Extended Mode Touch Screen | ||||
|     //             Reserved Addresses      0x302170 | ||||
|     static constexpr uint32_t BIST_EN           = 0x302174;  //    1    0                r/w     BIST Memory Mapping Enable | ||||
|     //             Reserved Addr           0x302178 | ||||
|     //             Reserved Addr           0x30217C | ||||
|     static constexpr uint32_t TRIM              = 0x302180;  //    8    0                r/w     Internal Clock Trimming | ||||
|     static constexpr uint32_t ANA_COMP          = 0x302184;  //    8    0                r/w     Analog Control Register | ||||
|     static constexpr uint32_t SPI_WIDTH         = 0x302188;  //    3    0                r/w     QSPI Bus Width Setting | ||||
|     static constexpr uint32_t TOUCH_DIRECT_XY   = 0x30218C;  //   32    -                  r     Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16) | ||||
|     static constexpr uint32_t TOUCH_DIRECT_Z1Z2 = 0x302190;  //   32    -                  r     Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16) | ||||
|     //             Reserved Addresses      0x302194 - 0x302560 | ||||
|     static constexpr uint32_t DATESTAMP         = 0x320564;  //  128    -                  r     Stamp Date Code | ||||
|     static constexpr uint32_t CMDB_SPACE        = 0x302574;  //   12    0xFFC            r/w     Command DL Space Available | ||||
|     static constexpr uint32_t CMDB_WRITE        = 0x302578;  //   32    0                  w     Command DL Write | ||||
|  | ||||
|     static constexpr uint32_t TRACKER           = 0x309000;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8) | ||||
|     static constexpr uint32_t TRACKER_1         = 0x309004;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8) | ||||
|     static constexpr uint32_t TRACKER_2         = 0x309008;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8) | ||||
|     static constexpr uint32_t TRACKER_3         = 0x30900C;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8) | ||||
|     static constexpr uint32_t TRACKER_4         = 0x309010;  //   32    0x00000000       r/w     Track Register (Track Value MSB16; Tag Value - LSB8) | ||||
|  | ||||
|     static constexpr uint32_t MEDIAFIFO_READ    = 0x309014;  //   32    0x00000000       r/w     Media FIFO read pointer | ||||
|     static constexpr uint32_t MEDIAFIFO_WRITE   = 0x309018;  //   32    0x00000000       r/w     Media FIFO write pointer | ||||
|   }; | ||||
| } | ||||
| @@ -0,0 +1,128 @@ | ||||
| /***************** | ||||
|  * resolutions.h * | ||||
|  *****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2019 - Aleph Objects, Inc.                  * | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /*** | ||||
|  * The FT8xx has odd registers that don't correspond to timing values in | ||||
|  * display datasheets. This macro computes the register values using the | ||||
|  * formulas given in the document: | ||||
|  * | ||||
|  *     Bridgetek Application Note | ||||
|  *     AN_336 FT8xx | ||||
|  *     Selecting an LCD Display | ||||
|  *     Version 2.1 | ||||
|  *     Issue Date: 2017-11-14 | ||||
|  * | ||||
|  */ | ||||
| #define COMPUTE_REGS_FROM_DATASHEET \ | ||||
|     constexpr uint16_t Hoffset              = thfp + thb - 1; \ | ||||
|     constexpr uint16_t Hcycle               = th; \ | ||||
|     constexpr uint16_t Hsync0               = thfp - 1 ; \ | ||||
|     constexpr uint16_t Hsync1               = thfp + thpw - 1; \ | ||||
|     constexpr uint16_t Voffset              = tvfp + tvb - 1; \ | ||||
|     constexpr uint16_t Vcycle               = tv; \ | ||||
|     constexpr uint16_t Vsync0               = tvfp - 1; \ | ||||
|     constexpr uint16_t Vsync1               = tvfp + tvpw - 1; \ | ||||
|     static_assert(thfp + thb + Hsize == th, "Mismatch in display th"); \ | ||||
|     static_assert(tvfp + tvb + Vsize == tv, "Mismatch in display tv"); | ||||
|  | ||||
| #ifdef TOUCH_UI_320x240 | ||||
|   namespace FTDI { | ||||
|     constexpr uint8_t Pclk                 =    8; | ||||
|     constexpr uint8_t Pclkpol              =    0; | ||||
|     constexpr uint16_t Hsize               =  320; | ||||
|     constexpr uint16_t Vsize               =  240; | ||||
|     constexpr uint16_t Vsync0              =    0; | ||||
|     constexpr uint16_t Vsync1              =    2; | ||||
|     constexpr uint16_t Voffset             =   13; | ||||
|     constexpr uint16_t Vcycle              =  263; | ||||
|     constexpr uint16_t Hsync0              =    0; | ||||
|     constexpr uint16_t Hsync1              =   10; | ||||
|     constexpr uint16_t Hoffset             =   70; | ||||
|     constexpr uint16_t Hcycle              =  408; | ||||
|  | ||||
|     constexpr uint32_t default_transform_a =  0x000054ad; | ||||
|     constexpr uint32_t default_transform_b =  0xffffff52; | ||||
|     constexpr uint32_t default_transform_c =  0xfff7f6e4; | ||||
|     constexpr uint32_t default_transform_d =  0x00000065; | ||||
|     constexpr uint32_t default_transform_e =  0xffffbe3b; | ||||
|     constexpr uint32_t default_transform_f =  0x00f68e75; | ||||
|   } | ||||
|  | ||||
| #elif defined(TOUCH_UI_480x272) | ||||
|   namespace FTDI { | ||||
|     constexpr uint8_t  Pclk                 =    7; | ||||
|     constexpr uint8_t  Pclkpol              =    1; | ||||
|     constexpr uint16_t Hsize                =  480; | ||||
|     constexpr uint16_t Vsize                =  272; | ||||
|  | ||||
|     constexpr uint16_t th                   =  525; // One horizontal line | ||||
|     constexpr uint16_t thfp                 =   43; // HS Front porch | ||||
|     constexpr uint16_t thb                  =    2; // HS Back porch (blanking) | ||||
|     constexpr uint16_t thpw                 =   41; // HS pulse width | ||||
|  | ||||
|     constexpr uint16_t tv                   =  286; // Vertical period time | ||||
|     constexpr uint16_t tvfp                 =   12; // VS Front porch | ||||
|     constexpr uint16_t tvb                  =    2; // VS Back porch (blanking) | ||||
|     constexpr uint16_t tvpw                 =   10; // VS pulse width | ||||
|  | ||||
|     COMPUTE_REGS_FROM_DATASHEET | ||||
|  | ||||
|     constexpr uint32_t default_transform_a  =  0x00008100; | ||||
|     constexpr uint32_t default_transform_b  =  0x00000000; | ||||
|     constexpr uint32_t default_transform_c  =  0xFFF18000; | ||||
|     constexpr uint32_t default_transform_d  =  0x00000000; | ||||
|     constexpr uint32_t default_transform_e  =  0xFFFFB100; | ||||
|     constexpr uint32_t default_transform_f  =  0x0120D000; | ||||
|   } | ||||
|  | ||||
| #elif defined(TOUCH_UI_800x480) | ||||
|   namespace FTDI { | ||||
|     constexpr uint8_t  Pclk                 =    3; | ||||
|     constexpr uint8_t  Pclkpol              =    1; | ||||
|     constexpr uint16_t Hsize                =  800; | ||||
|     constexpr uint16_t Vsize                =  480; | ||||
|  | ||||
|     constexpr uint16_t th                   = 1056; // One horizontal line | ||||
|     constexpr uint16_t thfp                 =  210; // HS Front porch | ||||
|     constexpr uint16_t thb                  =   46; // HS Back porch (blanking) | ||||
|     constexpr uint16_t thpw                 =   23; // HS pulse width | ||||
|  | ||||
|     constexpr uint16_t tv                   =  525; // Vertical period time | ||||
|     constexpr uint16_t tvfp                 =   22; // VS Front porch | ||||
|     constexpr uint16_t tvb                  =   23; // VS Back porch (blanking) | ||||
|     constexpr uint16_t tvpw                 =   10; // VS pulse width | ||||
|  | ||||
|     COMPUTE_REGS_FROM_DATASHEET | ||||
|  | ||||
|     constexpr uint32_t default_transform_a  =  0x0000D8B9; | ||||
|     constexpr uint32_t default_transform_b  =  0x00000124; | ||||
|     constexpr uint32_t default_transform_c  =  0xFFE23926; | ||||
|     constexpr uint32_t default_transform_d  =  0xFFFFFF51; | ||||
|     constexpr uint32_t default_transform_e  =  0xFFFF7E4F; | ||||
|     constexpr uint32_t default_transform_f  =  0x01F0AF70; | ||||
|   } | ||||
|  | ||||
| #else | ||||
|   #error Unknown or no LULZBOT_TOUCH_UI display resolution specified. To add a display resolution, modify "ftdi_eve_resolutions.h" | ||||
| #endif | ||||
| @@ -0,0 +1,178 @@ | ||||
| /*********** | ||||
|  * spi.cpp * | ||||
|  ***********/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_basic.h" | ||||
|  | ||||
| #ifdef FTDI_BASIC | ||||
|  | ||||
| /********************************* SPI Functions *********************************/ | ||||
|  | ||||
| namespace FTDI { | ||||
|   #if !defined(CLCD_USE_SOFT_SPI) | ||||
|     SPISettings SPI::spi_settings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0); | ||||
|   #endif | ||||
|  | ||||
|   void SPI::spi_init (void) { | ||||
|     SET_OUTPUT(CLCD_MOD_RESET); // Module Reset (a.k.a. PD, not SPI) | ||||
|     WRITE(CLCD_MOD_RESET, 0); // start with module in power-down | ||||
|  | ||||
|     SET_OUTPUT(CLCD_SPI_CS); | ||||
|     WRITE(CLCD_SPI_CS, 1); | ||||
|  | ||||
|     #ifdef SPI_FLASH_SS | ||||
|       SET_OUTPUT(SPI_FLASH_SS); | ||||
|       WRITE(SPI_FLASH_SS, 1); | ||||
|     #endif | ||||
|  | ||||
|     #ifdef CLCD_USE_SOFT_SPI | ||||
|       SET_OUTPUT(CLCD_SOFT_SPI_MOSI); | ||||
|       WRITE(CLCD_SOFT_SPI_MOSI, 1); | ||||
|  | ||||
|       SET_OUTPUT(CLCD_SOFT_SPI_SCLK); | ||||
|       WRITE(CLCD_SOFT_SPI_SCLK, 0); | ||||
|  | ||||
|       SET_INPUT_PULLUP(CLCD_SOFT_SPI_MISO); | ||||
|     #else | ||||
|       ::SPI.begin(); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   #ifdef CLCD_USE_SOFT_SPI | ||||
|     uint8_t SPI::_soft_spi_xfer (uint8_t spiOutByte) { | ||||
|       uint8_t spiIndex  = 0x80; | ||||
|       uint8_t spiInByte = 0; | ||||
|       uint8_t k; | ||||
|  | ||||
|       noInterrupts(); | ||||
|       for(k = 0; k <8; k++) {  // Output and Read each bit of spiOutByte and spiInByte | ||||
|         if (spiOutByte & spiIndex) {   // Output MOSI Bit | ||||
|           WRITE(CLCD_SOFT_SPI_MOSI, 1); | ||||
|         } | ||||
|         else { | ||||
|           WRITE(CLCD_SOFT_SPI_MOSI, 0); | ||||
|         } | ||||
|         WRITE(CLCD_SOFT_SPI_SCLK, 1);   // Pulse Clock | ||||
|         WRITE(CLCD_SOFT_SPI_SCLK, 0); | ||||
|  | ||||
|         if (READ(CLCD_SOFT_SPI_MISO)) { | ||||
|           spiInByte |= spiIndex; | ||||
|         } | ||||
|  | ||||
|         spiIndex >>= 1; | ||||
|       } | ||||
|       interrupts(); | ||||
|       return spiInByte; | ||||
|     } | ||||
|   #endif | ||||
|  | ||||
|   #ifdef CLCD_USE_SOFT_SPI | ||||
|     void SPI::_soft_spi_send (uint8_t spiOutByte) { | ||||
|       uint8_t spiIndex  = 0x80; | ||||
|       uint8_t k; | ||||
|  | ||||
|       noInterrupts(); | ||||
|       for(k = 0; k <8; k++) {         // Output each bit of spiOutByte | ||||
|         if (spiOutByte & spiIndex) {   // Output MOSI Bit | ||||
|           WRITE(CLCD_SOFT_SPI_MOSI, 1); | ||||
|         } | ||||
|         else { | ||||
|           WRITE(CLCD_SOFT_SPI_MOSI, 0); | ||||
|         } | ||||
|         WRITE(CLCD_SOFT_SPI_SCLK, 1);   // Pulse Clock | ||||
|         WRITE(CLCD_SOFT_SPI_SCLK, 0); | ||||
|  | ||||
|         spiIndex >>= 1; | ||||
|       } | ||||
|       interrupts(); | ||||
|     } | ||||
|   #endif | ||||
|  | ||||
|   void SPI::spi_read_bulk (void *data, uint16_t len) { | ||||
|     uint8_t* p = (uint8_t *)data; | ||||
|     #if !defined(CLCD_USE_SOFT_SPI) | ||||
|       ::SPI.transfer(p, len); | ||||
|     #else | ||||
|       while (len--) *p++ = spi_recv(); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   bool SPI::spi_verify_bulk (const void *data, uint16_t len) { | ||||
|     const uint8_t* p = (const uint8_t *)data; | ||||
|     while (len--) if (*p++ != spi_recv()) return false; | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   // CLCD SPI - Chip Select | ||||
|   void SPI::spi_ftdi_select (void) { | ||||
|     #if !defined(CLCD_USE_SOFT_SPI) | ||||
|       ::SPI.beginTransaction(spi_settings); | ||||
|     #endif | ||||
|     WRITE(CLCD_SPI_CS, 0); | ||||
|     delayMicroseconds(1); | ||||
|   } | ||||
|  | ||||
|   // CLCD SPI - Chip Deselect | ||||
|   void SPI::spi_ftdi_deselect (void) { | ||||
|     WRITE(CLCD_SPI_CS, 1); | ||||
|     #if !defined(CLCD_USE_SOFT_SPI) | ||||
|       ::SPI.endTransaction(); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   #ifdef SPI_FLASH_SS | ||||
|   // Serial SPI Flash SPI - Chip Select | ||||
|   void SPI::spi_flash_select () { | ||||
|     #if !defined(CLCD_USE_SOFT_SPI) | ||||
|     ::SPI.beginTransaction(spi_settings); | ||||
|     #endif | ||||
|     WRITE(SPI_FLASH_SS, 0); | ||||
|     delayMicroseconds(1); | ||||
|   } | ||||
|  | ||||
|   // Serial SPI Flash SPI - Chip Deselect | ||||
|   void SPI::spi_flash_deselect () { | ||||
|     WRITE(SPI_FLASH_SS, 1); | ||||
|     #if !defined(CLCD_USE_SOFT_SPI) | ||||
|     ::SPI.endTransaction(); | ||||
|     #endif | ||||
|   } | ||||
|   #endif | ||||
|  | ||||
|   // Not really a SPI signal... | ||||
|   void SPI::ftdi_reset (void) { | ||||
|     WRITE(CLCD_MOD_RESET, 0); | ||||
|     delay(6); /* minimum time for power-down is 5ms */ | ||||
|     WRITE(CLCD_MOD_RESET, 1); | ||||
|     delay(21); /* minimum time to allow from rising PD_N to first access is 20ms */ | ||||
|   } | ||||
|  | ||||
|   // Not really a SPI signal... | ||||
|   void SPI::test_pulse(void) | ||||
|   { | ||||
|     #ifdef CLCD_AUX_0 | ||||
|       WRITE(CLCD_AUX_0, 1); | ||||
|       delayMicroseconds(10); | ||||
|       WRITE(CLCD_AUX_0, 0); | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
| #endif // FTDI_BASIC | ||||
| @@ -0,0 +1,128 @@ | ||||
| /********* | ||||
|  * spi.h * | ||||
|  *********/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(CLCD_USE_SOFT_SPI) | ||||
|   #include <SPI.h> | ||||
| #endif | ||||
|  | ||||
| namespace FTDI { | ||||
|   namespace SPI { | ||||
|     #if !defined(CLCD_USE_SOFT_SPI) | ||||
|       extern SPISettings spi_settings; | ||||
|     #endif | ||||
|  | ||||
|     uint8_t  _soft_spi_xfer (uint8_t val); | ||||
|     void     _soft_spi_send (uint8_t val); | ||||
|  | ||||
|     void     spi_init           (); | ||||
|  | ||||
|     void     spi_ftdi_select    (); | ||||
|     void     spi_ftdi_deselect  (); | ||||
|  | ||||
|     void     spi_flash_select   (); | ||||
|     void     spi_flash_deselect (); | ||||
|  | ||||
|     inline uint8_t spi_recv() { | ||||
|       #ifdef CLCD_USE_SOFT_SPI | ||||
|         return _soft_spi_xfer(0x00); | ||||
|       #else | ||||
|         return ::SPI.transfer(0x00); | ||||
|       #endif | ||||
|     }; | ||||
|  | ||||
|     inline void spi_send (uint8_t val) { | ||||
|       #ifdef CLCD_USE_SOFT_SPI | ||||
|         _soft_spi_send(val); | ||||
|       #else | ||||
|         ::SPI.transfer(val); | ||||
|       #endif | ||||
|     }; | ||||
|  | ||||
|     inline void       spi_write_8    (uint8_t val)    {spi_send(val);}; | ||||
|     inline uint8_t    spi_read_8     ()               {return spi_recv();}; | ||||
|  | ||||
|     namespace least_significant_byte_first { | ||||
|       inline void     spi_write_16   (uint16_t val)   {spi_send(val >> 0); | ||||
|                                                        spi_send(val >> 8);}; | ||||
|       inline void     spi_write_32   (uint32_t val)   {spi_send(val >> 0); | ||||
|                                                        spi_send(val >> 8); | ||||
|                                                        spi_send(val >> 16); | ||||
|                                                        spi_send(val >> 24);}; | ||||
|  | ||||
|       inline uint8_t  spi_read_8     ()               {return spi_recv();}; | ||||
|       inline uint16_t spi_read_16    ()               {return (((uint16_t) spi_recv()) <<  0) | | ||||
|                                                               (((uint16_t) spi_recv()) <<  8);}; | ||||
|       inline uint32_t spi_read_32    ()               {return (((uint32_t) spi_recv()) <<  0) | | ||||
|                                                               (((uint32_t) spi_recv()) <<  8) | | ||||
|                                                               (((uint32_t) spi_recv()) << 16) | | ||||
|                                                               (((uint32_t) spi_recv()) << 24);}; | ||||
|     } | ||||
|  | ||||
|     namespace most_significant_byte_first { | ||||
|       inline void     spi_write_16   (uint16_t val)   {spi_send(val >> 8); | ||||
|                                                        spi_send(val >> 0);}; | ||||
|       inline void     spi_write_24   (uint32_t val)   {spi_send(val >> 16); | ||||
|                                                        spi_send(val >> 8); | ||||
|                                                        spi_send(val >> 0);}; | ||||
|       inline void     spi_write_32   (uint32_t val)   {spi_send(val >> 24); | ||||
|                                                        spi_send(val >> 16); | ||||
|                                                        spi_send(val >> 8); | ||||
|                                                        spi_send(val >> 0);}; | ||||
|  | ||||
|       inline uint16_t spi_read_16    ()               {return (((uint16_t) spi_recv()) <<  8) | | ||||
|                                                               (((uint16_t) spi_recv()) <<  0);}; | ||||
|       inline uint32_t spi_read_32    ()               {return (((uint32_t) spi_recv()) << 24) | | ||||
|                                                               (((uint32_t) spi_recv()) << 16) | | ||||
|                                                               (((uint32_t) spi_recv()) <<  8) | | ||||
|                                                               (((uint32_t) spi_recv()) <<  0);}; | ||||
|     } | ||||
|  | ||||
|     inline uint8_t ram_write(const uint8_t *p) {return *p;} | ||||
|     inline uint8_t pgm_write(const uint8_t *p) {return pgm_read_byte(p);} | ||||
|  | ||||
|     typedef uint8_t (*bulk_write_op)(const uint8_t*); | ||||
|  | ||||
|     // Generic template for function for writing multiple bytes, plus padding bytes. | ||||
|     // The template parameter op is an inlineable function which is applied to each byte. | ||||
|  | ||||
|     template<bulk_write_op byte_op> | ||||
|     void spi_write_bulk(const void *data, uint16_t len, uint8_t padding) { | ||||
|       const uint8_t* p = (const uint8_t *)data; | ||||
|       while (len--)     spi_send(byte_op(p++)); | ||||
|       while (padding--) spi_send(0); | ||||
|     } | ||||
|  | ||||
|     template<bulk_write_op byte_op> | ||||
|     void spi_write_bulk(const void *data, uint16_t len) { | ||||
|       const uint8_t* p = (const uint8_t *)data; | ||||
|       while (len--) spi_send(byte_op(p++)); | ||||
|     } | ||||
|  | ||||
|     void spi_read_bulk(      void *data, uint16_t len); | ||||
|     bool spi_verify_bulk(const void *data, uint16_t len); | ||||
|  | ||||
|     void ftdi_reset(void); | ||||
|     void test_pulse(void); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										211
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/compat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/compat.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,211 @@ | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #ifdef __MARLIN_FIRMWARE__ | ||||
|   // Marlin will define the I/O functions for us | ||||
|  | ||||
|   #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|     #define FTDI_BASIC | ||||
|     #define FTDI_EXTENDED | ||||
|   #endif | ||||
| #else | ||||
|   #include "Arduino.h" | ||||
|  | ||||
|   #if !defined(CLCD_USE_SOFT_SPI) | ||||
|     #include "SPI.h" | ||||
|   #endif | ||||
|  | ||||
|   namespace fast_io { | ||||
|  | ||||
|     template<typename port_t,uint8_t bits> | ||||
|     struct port_pin { | ||||
|       typedef port_t port; | ||||
|       static inline void set_high()         {port::port() = (port::port() |   bits);} | ||||
|       static inline void set_low()          {port::port() = (port::port() & (~bits));} | ||||
|       static inline void set_input()        {port::ddr()  = (port::ddr()  & (~bits));} | ||||
|       static inline void set_input_pullup() {set_input(); set_high();} | ||||
|       static inline void set_output()       {port::ddr()  = (port::ddr()  |   bits);} | ||||
|       static inline uint8_t read()          {return port::pin() & bits;} | ||||
|       static inline void write(bool v)      {if (v) set_high(); else set_low();} | ||||
|     }; | ||||
|  | ||||
|     #define MAKE_AVR_PORT_PINS(ID) \ | ||||
|       struct port_##ID { \ | ||||
|         static volatile uint8_t &pin()  {return PIN##ID;}; \ | ||||
|         static volatile uint8_t &port() {return PORT##ID;}; \ | ||||
|         static volatile uint8_t &ddr()  {return DDR##ID;}; \ | ||||
|       }; \ | ||||
|       typedef port_pin<port_##ID, 0b00000001> AVR_##ID##0; \ | ||||
|       typedef port_pin<port_##ID, 0b00000010> AVR_##ID##1; \ | ||||
|       typedef port_pin<port_##ID, 0b00000100> AVR_##ID##2; \ | ||||
|       typedef port_pin<port_##ID, 0b00001000> AVR_##ID##3; \ | ||||
|       typedef port_pin<port_##ID, 0b00010000> AVR_##ID##4; \ | ||||
|       typedef port_pin<port_##ID, 0b00100000> AVR_##ID##5; \ | ||||
|       typedef port_pin<port_##ID, 0b01000000> AVR_##ID##6; \ | ||||
|       typedef port_pin<port_##ID, 0b10000000> AVR_##ID##7; | ||||
|  | ||||
|     #ifdef PORTA | ||||
|       MAKE_AVR_PORT_PINS(A); | ||||
|     #endif | ||||
|     #ifdef PORTB | ||||
|       MAKE_AVR_PORT_PINS(B); | ||||
|     #endif | ||||
|     #ifdef PORTC | ||||
|       MAKE_AVR_PORT_PINS(C); | ||||
|     #endif | ||||
|     #ifdef PORTD | ||||
|       MAKE_AVR_PORT_PINS(D); | ||||
|     #endif | ||||
|     #ifdef PORTE | ||||
|       MAKE_AVR_PORT_PINS(E); | ||||
|     #endif | ||||
|     #ifdef PORTF | ||||
|       MAKE_AVR_PORT_PINS(F); | ||||
|     #endif | ||||
|     #ifdef PORTG | ||||
|       MAKE_AVR_PORT_PINS(G); | ||||
|     #endif | ||||
|     #ifdef PORTH | ||||
|       MAKE_AVR_PORT_PINS(H); | ||||
|     #endif | ||||
|     #ifdef PORTJ | ||||
|       MAKE_AVR_PORT_PINS(J); | ||||
|     #endif | ||||
|     #ifdef PORTK | ||||
|       MAKE_AVR_PORT_PINS(K); | ||||
|     #endif | ||||
|     #ifdef PORTL | ||||
|       MAKE_AVR_PORT_PINS(L); | ||||
|     #endif | ||||
|     #ifdef PORTQ | ||||
|       MAKE_AVR_PORT_PINS(Q); | ||||
|     #endif | ||||
|     #ifdef PORTR | ||||
|       MAKE_AVR_PORT_PINS(R); | ||||
|     #endif | ||||
|  | ||||
|     #undef MAKE_AVR_PORT_PINS | ||||
|  | ||||
|     template<uint8_t p> | ||||
|     struct arduino_digital_pin { | ||||
|       static constexpr uint8_t pin = p; | ||||
|       static inline void set_high()          {digitalWrite(p, HIGH);} | ||||
|       static inline void set_low()           {digitalWrite(p, LOW);} | ||||
|       static inline void set_input()         {pinMode(p, INPUT);} | ||||
|       static inline void set_input_pullup()  {pinMode(p, INPUT_PULLUP);} | ||||
|       static inline void set_output()        {pinMode(p, OUTPUT);} | ||||
|       static inline uint8_t read()           {return digitalRead(p);} | ||||
|       static inline void write(bool v)       {digitalWrite(p, v ? HIGH : LOW);} | ||||
|     }; | ||||
|  | ||||
|     #define MAKE_ARDUINO_PINS(ID) typedef arduino_digital_pin<ID> ARDUINO_DIGITAL_##ID; | ||||
|     MAKE_ARDUINO_PINS( 0); | ||||
|     MAKE_ARDUINO_PINS( 1); | ||||
|     MAKE_ARDUINO_PINS( 2); | ||||
|     MAKE_ARDUINO_PINS( 3); | ||||
|     MAKE_ARDUINO_PINS( 4); | ||||
|     MAKE_ARDUINO_PINS( 5); | ||||
|     MAKE_ARDUINO_PINS( 6); | ||||
|     MAKE_ARDUINO_PINS( 7); | ||||
|     MAKE_ARDUINO_PINS( 8); | ||||
|     MAKE_ARDUINO_PINS( 9); | ||||
|     MAKE_ARDUINO_PINS(10); | ||||
|     MAKE_ARDUINO_PINS(11); | ||||
|     MAKE_ARDUINO_PINS(12); | ||||
|     MAKE_ARDUINO_PINS(13); | ||||
|     MAKE_ARDUINO_PINS(14); | ||||
|     MAKE_ARDUINO_PINS(15); | ||||
|     MAKE_ARDUINO_PINS(16); | ||||
|     MAKE_ARDUINO_PINS(17); | ||||
|     MAKE_ARDUINO_PINS(18); | ||||
|     MAKE_ARDUINO_PINS(19); | ||||
|     MAKE_ARDUINO_PINS(10); | ||||
|     MAKE_ARDUINO_PINS(21); | ||||
|     MAKE_ARDUINO_PINS(22); | ||||
|     MAKE_ARDUINO_PINS(23); | ||||
|     MAKE_ARDUINO_PINS(24); | ||||
|     MAKE_ARDUINO_PINS(25); | ||||
|     MAKE_ARDUINO_PINS(26); | ||||
|     MAKE_ARDUINO_PINS(27); | ||||
|     MAKE_ARDUINO_PINS(28); | ||||
|     MAKE_ARDUINO_PINS(29); | ||||
|     MAKE_ARDUINO_PINS(30); | ||||
|     MAKE_ARDUINO_PINS(31); | ||||
|     MAKE_ARDUINO_PINS(32); | ||||
|     MAKE_ARDUINO_PINS(33); | ||||
|     MAKE_ARDUINO_PINS(34); | ||||
|     MAKE_ARDUINO_PINS(35); | ||||
|     MAKE_ARDUINO_PINS(36); | ||||
|     MAKE_ARDUINO_PINS(37); | ||||
|     MAKE_ARDUINO_PINS(38); | ||||
|     MAKE_ARDUINO_PINS(39); | ||||
|     MAKE_ARDUINO_PINS(40); | ||||
|     MAKE_ARDUINO_PINS(41); | ||||
|     MAKE_ARDUINO_PINS(42); | ||||
|     MAKE_ARDUINO_PINS(43); | ||||
|     MAKE_ARDUINO_PINS(44); | ||||
|     MAKE_ARDUINO_PINS(45); | ||||
|     MAKE_ARDUINO_PINS(46); | ||||
|     MAKE_ARDUINO_PINS(47); | ||||
|     MAKE_ARDUINO_PINS(48); | ||||
|     MAKE_ARDUINO_PINS(49); | ||||
|     MAKE_ARDUINO_PINS(50); | ||||
|     MAKE_ARDUINO_PINS(51); | ||||
|     MAKE_ARDUINO_PINS(52); | ||||
|     MAKE_ARDUINO_PINS(53); | ||||
|     #undef MAKE_ARDUINO_PINS | ||||
|   } // namespace fast_io | ||||
|  | ||||
|   #define SET_INPUT(pin)               fast_io::pin::set_input() | ||||
|   #define SET_INPUT_PULLUP(pin)        fast_io::pin::set_input(); fast_io::pin::set_high() | ||||
|   #define SET_OUTPUT(pin)              fast_io::pin::set_output() | ||||
|   #define READ(pin)                    fast_io::pin::read() | ||||
|   #define WRITE(pin, value)            fast_io::pin::write(value) | ||||
|  | ||||
|   #ifndef pgm_read_word_far | ||||
|   #define pgm_read_word_far pgm_read_word | ||||
|   #endif | ||||
|  | ||||
|   #ifndef pgm_read_dword_far | ||||
|   #define pgm_read_dword_far pgm_read_dword | ||||
|   #endif | ||||
|  | ||||
|   #ifndef pgm_read_ptr_far | ||||
|   #define pgm_read_ptr_far pgm_read_ptr | ||||
|   #endif | ||||
|  | ||||
|   #define SERIAL_ECHO_START() | ||||
|   #define SERIAL_ECHOLNPGM(str)        Serial.println(F(str)) | ||||
|   #define SERIAL_ECHOPGM(str)          Serial.print(F(str)) | ||||
|   #define SERIAL_ECHOLNPAIR(str, val) {Serial.print(F(str)); Serial.println(val);} | ||||
|   #define SERIAL_ECHOPAIR(str, val)   {Serial.print(F(str)); Serial.print(val);} | ||||
|  | ||||
|   #define safe_delay delay | ||||
|  | ||||
|   // Remove compiler warning on an unused variable | ||||
|   #ifndef UNUSED | ||||
|     #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) | ||||
|       #define UNUSED(X) (void)X | ||||
|     #else | ||||
|       #define UNUSED(x) ((void)(x)) | ||||
|     #endif | ||||
|   #endif | ||||
| #endif //!defined(__MARLIN_FIRMWARE__) | ||||
| @@ -0,0 +1,49 @@ | ||||
| /***************** | ||||
|  * bitmap_info.h * | ||||
|  *****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #ifndef FORCEDINLINE | ||||
|   #define FORCEDINLINE __attribute__((always_inline)) inline | ||||
| #endif | ||||
|  | ||||
| namespace FTDI { | ||||
|    // 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 to read them). | ||||
|    // Plus, by inlining, all the equations are evaluated at compile-time as everything | ||||
|    // should be a constant. | ||||
|  | ||||
|    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_offset; | ||||
|      const uint16_t width; | ||||
|      const uint16_t height; | ||||
|    } bitmap_info_t; | ||||
|  | ||||
|    FORCEDINLINE uint32_t BITMAP_SOURCE (const bitmap_info_t& info) {return BITMAP_SOURCE (ftdi_memory_map::RAM_G + info.RAMG_offset);}; | ||||
|    FORCEDINLINE uint32_t BITMAP_LAYOUT (const bitmap_info_t& info) {return BITMAP_LAYOUT (info.format, info.linestride, info.height);}; | ||||
|    FORCEDINLINE uint32_t BITMAP_SIZE   (const bitmap_info_t& info) {return BITMAP_SIZE   (info.filter, info.wrapx, info.wrapy, info.width, info.height);} | ||||
| } | ||||
| @@ -0,0 +1,29 @@ | ||||
| /************************* | ||||
|  * command_processor.cpp * | ||||
|  *************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Marcio Teixeira 2018                                        * | ||||
|  *                                                                          * | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_extended.h" | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
|  | ||||
| CommandProcessor::btn_style_func_t  *CommandProcessor::_btn_style_callback = CommandProcessor::default_button_style_func; | ||||
| bool CommandProcessor::is_tracking = false; | ||||
|  | ||||
| #endif // FTDI_EXTENDED | ||||
| @@ -0,0 +1,347 @@ | ||||
| /*********************** | ||||
|  * command_processor.h * | ||||
|  ***********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| typedef struct { | ||||
|   uint32_t bg; | ||||
|   uint32_t grad; | ||||
|   uint32_t fg; | ||||
|   uint32_t rgb; | ||||
| } btn_colors; | ||||
|  | ||||
| /**************************** Enhanced Command Processor **************************/ | ||||
|  | ||||
| /* The CommandProcessor class wraps the CommandFifo with several features to make | ||||
|  * defining user interfaces much easier. | ||||
|  * | ||||
|  *   - Implements chaining on all methods | ||||
|  *   - Automatically adds text to button, toggle, text and keys. | ||||
|  *   - Constrains all widgets to fit inside a box for ease of layout. | ||||
|  *   - Font size is specified using a chained modifier. | ||||
|  *   - Option argument is given the default OPT_3D value. | ||||
|  */ | ||||
|  | ||||
| class CommandProcessor : public CLCD::CommandFifo { | ||||
|   public: | ||||
|     static constexpr uint8_t STYLE_DISABLED = 0x80; | ||||
|  | ||||
|   private: | ||||
|     static bool default_button_style_func(CommandProcessor &, uint8_t tag, uint8_t & /*style*/, uint16_t &options, bool) { | ||||
|       if (tag != 0 && FTDI::EventLoop::get_pressed_tag() == tag) { | ||||
|         options = FTDI::OPT_FLAT; | ||||
|       } | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     typedef bool btn_style_func_t(CommandProcessor &cmd, uint8_t tag, uint8_t &style, uint16_t &options, bool post); | ||||
|  | ||||
|     static btn_style_func_t  *_btn_style_callback; | ||||
|     static bool is_tracking; | ||||
|     int8_t  _font = 26, _tag = 0; | ||||
|     uint8_t _style = 0; | ||||
|  | ||||
|   protected: | ||||
|     // Returns the cannonical thickness of a widget (i.e. the height of a toggle element) | ||||
|     uint16_t widget_thickness() { | ||||
|       CLCD::FontMetrics fm(_font); | ||||
|       return fm.height * 20.0/16; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE void linear_widget_box(int16_t &x, int16_t &y, int16_t &w, int16_t &h, bool tracker = false) { | ||||
|       const uint16_t th = widget_thickness()/2; | ||||
|       if (w > h) { | ||||
|         x += tracker ? th * 2.5 : th; | ||||
|         y += h/2  - th/2; | ||||
|         w -= tracker ? th * 5.0 : th * 2; | ||||
|         h  = th; | ||||
|       } else { | ||||
|         x += w/2  - th/2; | ||||
|         y += tracker ? th * 2.5 : th; | ||||
|         w  = th; | ||||
|         h -= tracker ? th * 5.0 : th * 2; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE uint16_t circular_widget_box(int16_t &x, int16_t &y, int16_t &w, int16_t &h) { | ||||
|       const uint16_t r = min(w,h)/2; | ||||
|       x += w/2; | ||||
|       y += h/2; | ||||
|       w  = 1; | ||||
|       h  = 1; | ||||
|       return r; | ||||
|     } | ||||
|  | ||||
|   public: | ||||
|     // Helper method for setting all colors at once | ||||
|     inline CommandProcessor& colors(const btn_colors &colors) { | ||||
|       cmd(FTDI::COLOR_RGB(colors.rgb)) | ||||
|         .gradcolor(colors.grad) | ||||
|         .fgcolor(colors.fg) | ||||
|         .bgcolor(colors.bg); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     inline CommandProcessor& bitmap_size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) { | ||||
|       cmd(FTDI::BITMAP_SIZE(filter, wrapx, wrapy, width, height)); | ||||
|       #if FTDI_API_LEVEL >= 810 | ||||
|         if (FTDI::ftdi_chip >= 810) | ||||
|           cmd(FTDI::BITMAP_SIZE_H(width >> 9, height >> 9)); | ||||
|       #endif | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     inline CommandProcessor& bitmap_layout(uint8_t format, uint16_t linestride, uint16_t height) { | ||||
|       cmd(FTDI::BITMAP_LAYOUT(format, linestride, height)); | ||||
|       #if FTDI_API_LEVEL >= 810 | ||||
|         if (FTDI::ftdi_chip >= 810) | ||||
|           cmd(FTDI::BITMAP_LAYOUT_H(linestride >> 10, height >> 9)); | ||||
|       #endif | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     inline CommandProcessor& set_button_style_callback(const btn_style_func_t *func) { | ||||
|       _btn_style_callback = func ? func : default_button_style_func; | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     inline CommandProcessor& tag      (uint8_t  tag)              {_tag = tag; cmd(FTDI::TAG(tag)); return *this;} | ||||
|  | ||||
|     inline CommandProcessor& font     (int16_t  font)             {_font = font; return *this;} | ||||
|  | ||||
|     inline CommandProcessor& enabled  (bool enabled) { | ||||
|       if (enabled) | ||||
|         _style &= ~STYLE_DISABLED; | ||||
|       else | ||||
|         _style |= STYLE_DISABLED; | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     inline CommandProcessor& style    (uint8_t style) { | ||||
|       _style = (_style & STYLE_DISABLED) | style; | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     // Wrap all the CommandFifo routines to allow method chaining | ||||
|  | ||||
|     inline CommandProcessor& cmd      (uint32_t cmd32)            {CLCD::CommandFifo::cmd(cmd32); return *this;} | ||||
|     inline CommandProcessor& cmd      (void* data, uint16_t len)  {CLCD::CommandFifo::cmd(data, len); return *this;} | ||||
|     inline CommandProcessor& execute()                            {CLCD::CommandFifo::execute(); return *this;} | ||||
|  | ||||
|     inline CommandProcessor& fgcolor  (uint32_t rgb)              {CLCD::CommandFifo::fgcolor(rgb); return *this;} | ||||
|     inline CommandProcessor& bgcolor  (uint32_t rgb)              {CLCD::CommandFifo::bgcolor(rgb); return *this;} | ||||
|     inline CommandProcessor& gradcolor(uint32_t rgb)              {CLCD::CommandFifo::gradcolor(rgb); return *this;} | ||||
|  | ||||
|     inline CommandProcessor& snapshot (uint32_t ptr)              {CLCD::CommandFifo::snapshot(ptr); return *this;} | ||||
|  | ||||
|     inline CommandProcessor& loadimage(uint32_t ptr, uint32_t options) | ||||
|                                                                   {CLCD::CommandFifo::loadimage(ptr, options); return *this;} | ||||
|     inline CommandProcessor& sketch   (int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format) | ||||
|                                                                   {CLCD::CommandFifo::sketch(x, y, w, h, ptr, format); return *this;} | ||||
|     inline CommandProcessor& screensaver  ()                      {CLCD::CommandFifo::screensaver(); return *this;} | ||||
|     #if FTDI_API_LEVEL >= 810 | ||||
|     inline CommandProcessor& setbase  (uint8_t base)              {CLCD::CommandFifo::setbase(base); return *this;} | ||||
|     #endif | ||||
|     inline CommandProcessor& loadidentity ()                      {CLCD::CommandFifo::loadidentity(); return *this;} | ||||
|     inline CommandProcessor& scale    (int32_t sx, int32_t sy)    {CLCD::CommandFifo::scale(sx,sy); return *this;} | ||||
|     inline CommandProcessor& rotate   (int32_t a)                 {CLCD::CommandFifo::rotate(a); return *this;} | ||||
|     inline CommandProcessor& translate(int32_t tx, int32_t ty)    {CLCD::CommandFifo::translate(tx,ty); return *this;} | ||||
|     inline CommandProcessor& setmatrix ()                         {CLCD::CommandFifo::setmatrix(); return *this;} | ||||
|     inline CommandProcessor& stop ()                              {CLCD::CommandFifo::stop(); return *this;} | ||||
|  | ||||
|     inline CommandProcessor& memzero  (uint32_t ptr, uint32_t size) | ||||
|                                                                   {CLCD::CommandFifo::memzero(ptr, size); return *this;} | ||||
|     inline CommandProcessor& memset   (uint32_t ptr, uint32_t val, uint32_t size) | ||||
|                                                                   {CLCD::CommandFifo::memset(ptr, val, size); return *this;} | ||||
|     inline CommandProcessor& memcpy   (uint32_t src, uint32_t dst, uint32_t size) | ||||
|                                                                   {CLCD::CommandFifo::memcpy(src, dst, size); return *this;} | ||||
|     inline CommandProcessor& memcrc   (uint32_t ptr, uint32_t num, uint32_t result) | ||||
|                                                                   {CLCD::CommandFifo::memcrc(ptr, num, result); return *this;} | ||||
|     inline CommandProcessor& memwrite (uint32_t ptr, uint32_t value) | ||||
|                                                                   {CLCD::CommandFifo::memwrite(ptr, value); return *this;} | ||||
|     inline CommandProcessor& inflate  (uint32_t ptr) | ||||
|                                                                   {CLCD::CommandFifo::inflate(ptr); return *this;} | ||||
|     inline CommandProcessor& getptr   (uint32_t result) | ||||
|                                                                   {CLCD::CommandFifo::getptr(result); return *this;} | ||||
|     inline CommandProcessor& getprops (uint32_t ptr, uint32_t width, uint32_t height) | ||||
|                                                                   {CLCD::CommandFifo::getprops(ptr, width, height); return *this;} | ||||
|  | ||||
|     #if FTDI_API_LEVEL >= 810 | ||||
|     inline CommandProcessor& setbitmap (uint32_t ptr, uint16_t fmt, uint16_t w, uint16_t h) | ||||
|                                                                   {CLCD::CommandFifo::setbitmap(ptr,fmt,w,h); return *this;} | ||||
|     inline CommandProcessor& snapshot2 (uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, uint16_t w, uint16_t h) | ||||
|                                                                   {CLCD::CommandFifo::snapshot2(fmt,ptr,x,y,w,h); return *this;} | ||||
|     inline CommandProcessor& mediafifo (uint32_t p, uint32_t s)   {CLCD::CommandFifo::mediafifo(p, s); return *this;} | ||||
|     inline CommandProcessor& playvideo(uint32_t options)          {CLCD::CommandFifo::playvideo(options); return *this;} | ||||
|     #endif | ||||
|  | ||||
|     inline CommandProcessor& gradient(int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1) | ||||
|                                                                   {CLCD::CommandFifo::gradient(x0,y0,rgb0,x1,y1,rgb1); return *this;} | ||||
|  | ||||
|     inline CommandProcessor& rectangle(int16_t x, int16_t y, int16_t w, int16_t h) { | ||||
|       using namespace FTDI; | ||||
|       CLCD::CommandFifo::cmd(BEGIN(RECTS)); | ||||
|       CLCD::CommandFifo::cmd(VERTEX2F(x*16,y*16)); | ||||
|       CLCD::CommandFifo::cmd(VERTEX2F((x+w)*16,(y+h)*16)); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     FORCEDINLINE CommandProcessor& toggle(int16_t x, int16_t y, int16_t w, int16_t h, T text, bool state, uint16_t options = FTDI::OPT_3D) { | ||||
|       CLCD::FontMetrics fm(_font); | ||||
|       const int16_t widget_h = fm.height * 20.0/16; | ||||
|       //const int16_t outer_bar_r = widget_h / 2; | ||||
|       //const int16_t knob_r      = outer_bar_r - 1.5; | ||||
|       // The y coordinate of the toggle is the baseline of the text, | ||||
|       // so we must introduce a fudge factor based on the line height to | ||||
|       // actually center the control. | ||||
|       const int16_t fudge_y = fm.height*5/16; | ||||
|       CLCD::CommandFifo::toggle(x + h/2, y + h/2 - widget_h/2 + fudge_y, w - h, _font, options, state); | ||||
|       CLCD::CommandFifo::str(text); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     // Contrained drawing routines. These constrain the widget inside a box for easier layout. | ||||
|     // The FORCEDINLINE ensures that the code is inlined so that all the math is done at compile time. | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& track_linear(int16_t x, int16_t y, int16_t w, int16_t h, int16_t tag) { | ||||
|       linear_widget_box(x, y, w, h, true); | ||||
|       CLCD::CommandFifo::track(x, y, w, h, tag); | ||||
|       is_tracking = true; | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& track_circular(int16_t x, int16_t y, int16_t w, int16_t h, int16_t tag) { | ||||
|       circular_widget_box(x,y, w, h); | ||||
|       CLCD::CommandFifo::track(x, y, w, h, tag); | ||||
|       is_tracking = true; | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     uint8_t track_tag (uint16_t &value) { | ||||
|       if (is_tracking) { | ||||
|         if (FTDI::EventLoop::is_touch_held()) { | ||||
|           return CLCD::get_tracker(value); | ||||
|         } else { | ||||
|           CLCD::CommandFifo::track(0, 0, 0, 0, 0); | ||||
|           CLCD::CommandFifo::execute(); | ||||
|           is_tracking = false; | ||||
|         } | ||||
|       } | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& clock(int16_t x, int16_t y, int16_t w, int16_t h, int16_t hr, int16_t m, int16_t s, int16_t ms, uint16_t options = FTDI::OPT_3D) { | ||||
|       const uint16_t r = circular_widget_box(x, y, w, h); | ||||
|       CLCD::CommandFifo::clock(x, y, r, options, hr, m, s, ms); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& gauge(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t major, uint16_t minor, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) { | ||||
|       const uint16_t r = circular_widget_box(x, y, w, h); | ||||
|       CLCD::CommandFifo::gauge(x, y, r, options, major, minor, val, range); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& dial(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t options = FTDI::OPT_3D) { | ||||
|       const uint16_t r = circular_widget_box(x, y, w, h); | ||||
|       CLCD::CommandFifo::dial(x, y, r, options, val); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& slider(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) { | ||||
|       linear_widget_box(x, y, w, h); | ||||
|       CLCD::CommandFifo::slider(x, y, w, h, options, val, range); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& progress(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) { | ||||
|       linear_widget_box(x, y, w, h); | ||||
|       CLCD::CommandFifo::progress(x, y, w, h, options, val, range); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& scrollbar(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t size, uint16_t range, uint16_t options = 0) { | ||||
|       linear_widget_box(x, y, w, h); | ||||
|       CLCD::CommandFifo::scrollbar(x, y, w, h, options, val, size, range); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     CommandProcessor& number(int16_t x, int16_t y, int16_t w, int16_t h, int32_t n, uint16_t options = FTDI::OPT_CENTER) { | ||||
|       using namespace FTDI; | ||||
|       CLCD::CommandFifo::number( | ||||
|         x + ((options & OPT_CENTERX) ? w/2 : ((options & OPT_RIGHTX) ? w : 0)), | ||||
|         y + ((options & OPT_CENTERY) ? h/2 : h), | ||||
|         _font, options, n); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     template<typename T> FORCEDINLINE | ||||
|     CommandProcessor& text(int16_t x, int16_t y, int16_t w, int16_t h, T text, uint16_t options = FTDI::OPT_CENTER) { | ||||
|       using namespace FTDI; | ||||
|       CLCD::CommandFifo::text( | ||||
|         x + ((options & OPT_CENTERX) ? w/2 : ((options & OPT_RIGHTX) ? w : 0)), | ||||
|         y + ((options & OPT_CENTERY) ? h/2 : h), | ||||
|         _font, options); | ||||
|       CLCD::CommandFifo::str(text); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& icon(int16_t x, int16_t y, int16_t w, int16_t h, const FTDI::bitmap_info_t& info, const float scale = 1) { | ||||
|       using namespace FTDI; | ||||
|       cmd(BEGIN(BITMAPS)); | ||||
|       if (scale != 1) { | ||||
|         cmd(BITMAP_TRANSFORM_A(uint32_t(float(256)/scale))); | ||||
|         cmd(BITMAP_TRANSFORM_E(uint32_t(float(256)/scale))); | ||||
|       } | ||||
|       cmd(BITMAP_SIZE(info.filter, info.wrapx, info.wrapy, info.width*scale, info.height*scale)); | ||||
|       cmd(VERTEX2F((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)); | ||||
|       } | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     CommandProcessor& button(int16_t x, int16_t y, int16_t w, int16_t h, T text, uint16_t options = FTDI::OPT_3D) { | ||||
|       using namespace FTDI; | ||||
|       bool styleModified = false; | ||||
|       if (_btn_style_callback) styleModified = _btn_style_callback(*this, _tag, _style, options, false); | ||||
|       CLCD::CommandFifo::button(x, y, w, h, _font, options); | ||||
|       CLCD::CommandFifo::str(text); | ||||
|       if (_btn_style_callback && styleModified) _btn_style_callback(*this, _tag, _style, options, true); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     CommandProcessor& keys(int16_t x, int16_t y, int16_t w, int16_t h, T keys, uint16_t options = FTDI::OPT_3D) { | ||||
|       CLCD::CommandFifo::keys(x, y, w, h, _font, options); | ||||
|       CLCD::CommandFifo::str(keys); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     FORCEDINLINE CommandProcessor& spinner(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t style = 0, uint16_t scale = 0) { | ||||
|       circular_widget_box(x, y, w, h); | ||||
|       CLCD::CommandFifo::spinner(x, y, style, scale); | ||||
|       return *this; | ||||
|     } | ||||
| }; | ||||
| @@ -0,0 +1,176 @@ | ||||
| /**************** | ||||
|  * dl_cache.cpp * | ||||
|  ****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_extended.h" | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
|  | ||||
| /* 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. | ||||
|  * | ||||
|  * Layout of Cache memory: | ||||
|  * | ||||
|  * The cache memory begins with a table at | ||||
|  * DL_CACHE_START: each table entry contains | ||||
|  * an address and size for a cached DL slot. | ||||
|  * | ||||
|  * Immediately following the table is the | ||||
|  * DL_FREE_ADDR, which points to free cache | ||||
|  * space; following this is occupied DL space, | ||||
|  * and after that free space that is yet to | ||||
|  * be used. | ||||
|  * | ||||
|  *  location        data        sizeof | ||||
|  * | ||||
|  *  DL_CACHE_START  slot0_addr     4 | ||||
|  *                  slot0_size     4 | ||||
|  *                  slot1_addr     4 | ||||
|  *                  slot1_size     4 | ||||
|  *                      ... | ||||
|  *                  slotN_addr     4 | ||||
|  *                  slotN_size     4 | ||||
|  *  DL_FREE_ADDR    dl_free_ptr    4 | ||||
|  *                  cached data | ||||
|  *                      ... | ||||
|  *  dl_free_ptr     empty space | ||||
|  *                      ... | ||||
|  */ | ||||
|  | ||||
| #define DL_CACHE_START   MAP::RAM_G_SIZE - 0xFFFF | ||||
| #define DL_FREE_ADDR     DL_CACHE_START + DL_CACHE_SLOTS * 8 | ||||
|  | ||||
| using namespace FTDI; | ||||
|  | ||||
| // The init function ensures all cache locations are marked as empty | ||||
|  | ||||
| void DLCache::init() { | ||||
|   CLCD::mem_write_32(DL_FREE_ADDR, DL_FREE_ADDR + 4); | ||||
|   for(uint8_t slot = 0; slot < DL_CACHE_SLOTS; slot++) { | ||||
|     save_slot(slot, 0, 0); | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool DLCache::has_data() { | ||||
|   return dl_size != 0; | ||||
| } | ||||
|  | ||||
| bool DLCache::wait_until_idle() { | ||||
|   const unsigned long startTime = millis(); | ||||
|   do { | ||||
|     if ((millis() - startTime) > 250) { | ||||
|       SERIAL_ECHO_START(); | ||||
|       SERIAL_ECHOLNPGM("Timeout on DL_Cache::Wait_Until_Idle()"); | ||||
|       CLCD::CommandFifo::reset(); | ||||
|       return false; | ||||
|     } | ||||
|     #ifdef __MARLIN_FIRMWARE__ | ||||
|       ExtUI::yield(); | ||||
|     #endif | ||||
|   } while (CLCD::CommandFifo::is_processing()); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| /* This caches the current display list in RAMG so | ||||
|  * that it can be appended later. The memory is | ||||
|  * dynamically allocated following DL_FREE_ADDR. | ||||
|  * | ||||
|  * If num_bytes is provided, then that many bytes | ||||
|  * will be reserved so that the cache may be re-written | ||||
|  * later with potentially a bigger DL. | ||||
|  */ | ||||
|  | ||||
| bool DLCache::store(uint32_t num_bytes /* = 0*/) { | ||||
|   CLCD::CommandFifo cmd; | ||||
|  | ||||
|   // Execute any commands already in the FIFO | ||||
|   cmd.execute(); | ||||
|   if (!wait_until_idle()) | ||||
|     return false; | ||||
|  | ||||
|   // Figure out how long the display list is | ||||
|   uint32_t new_dl_size = CLCD::mem_read_32(REG::CMD_DL) & 0x1FFF; | ||||
|   uint32_t free_space  = 0; | ||||
|   uint32_t dl_alloc    = 0; | ||||
|  | ||||
|   if (dl_addr == 0) { | ||||
|     // If we are allocating new space... | ||||
|     dl_addr     = CLCD::mem_read_32(DL_FREE_ADDR); | ||||
|     free_space  = MAP::RAM_G_SIZE - dl_addr; | ||||
|     dl_alloc    = num_bytes ? num_bytes : new_dl_size; | ||||
|     dl_size     = new_dl_size; | ||||
|   } else { | ||||
|     // Otherwise, we can only store as much space | ||||
|     // as was previously allocated. | ||||
|     free_space  = num_bytes ? num_bytes : dl_size; | ||||
|     dl_alloc    = 0; | ||||
|     dl_size     = new_dl_size; | ||||
|   } | ||||
|  | ||||
|   if (dl_size > free_space) { | ||||
|     // Not enough memory to cache the display list. | ||||
|     #ifdef UI_FRAMEWORK_DEBUG | ||||
|       SERIAL_ECHO_START(); | ||||
|       SERIAL_ECHOPAIR("Not enough space in GRAM to cache display list, free space: ", free_space); | ||||
|       SERIAL_ECHOLNPAIR(" Required: ", dl_size); | ||||
|     #endif | ||||
|     return false; | ||||
|   } else { | ||||
|     #ifdef UI_FRAMEWORK_DEBUG | ||||
|       SERIAL_ECHO_START(); | ||||
|       SERIAL_ECHOPAIR("Saving DL to RAMG cache, bytes: ", dl_size); | ||||
|       SERIAL_ECHOLNPAIR(" Free space: ", free_space); | ||||
|     #endif | ||||
|     cmd.memcpy(dl_addr, MAP::RAM_DL, dl_size); | ||||
|     cmd.execute(); | ||||
|     save_slot(dl_slot, dl_addr, dl_size); | ||||
|     if (dl_alloc > 0) { | ||||
|       // If we allocated space dynamically, then adjust dl_free_addr. | ||||
|       CLCD::mem_write_32(DL_FREE_ADDR, dl_addr + dl_alloc); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DLCache::save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size) { | ||||
|   CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 0, dl_addr); | ||||
|   CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 4, dl_size); | ||||
| } | ||||
|  | ||||
| void DLCache::load_slot() { | ||||
|   dl_addr  = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 0); | ||||
|   dl_size  = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 4); | ||||
| } | ||||
|  | ||||
| void DLCache::append() { | ||||
|   CLCD::CommandFifo cmd; | ||||
|   cmd.append(dl_addr, dl_size); | ||||
|   #ifdef UI_FRAMEWORK_DEBUG | ||||
|     cmd.execute(); | ||||
|     wait_until_idle(); | ||||
|     SERIAL_ECHO_START(); | ||||
|     SERIAL_ECHOPAIR("Appending to DL from RAMG cache, bytes: ", dl_size); | ||||
|     SERIAL_ECHOLNPAIR(" REG_CMD_DL: ", CLCD::mem_read_32(REG::CMD_DL)); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #endif // FTDI_EXTENDED | ||||
| @@ -0,0 +1,69 @@ | ||||
| /************** | ||||
|  * dl_cache.h * | ||||
|  **************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /******************* 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() { | ||||
|  *     DLCache dlcache(UNIQUE_ID); | ||||
|  * | ||||
|  *     if (dlcache.hasData()) { | ||||
|  *        dlcache.append(); | ||||
|  *     } else { | ||||
|  *        // Add stuff to the DL | ||||
|  *        dlcache.store(); | ||||
|  *     } | ||||
|  */ | ||||
| class DLCache { | ||||
|   private: | ||||
|     typedef FTDI::ftdi_registers  REG; | ||||
|     typedef FTDI::ftdi_memory_map MAP; | ||||
|  | ||||
|     uint8_t  dl_slot; | ||||
|     uint32_t dl_addr; | ||||
|     uint16_t dl_size; | ||||
|  | ||||
|     void load_slot(); | ||||
|     static void save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size); | ||||
|  | ||||
|     bool wait_until_idle(); | ||||
|  | ||||
|   public: | ||||
|     static void init(); | ||||
|  | ||||
|     DLCache(uint8_t slot) { | ||||
|       dl_slot = slot; | ||||
|       load_slot(); | ||||
|     } | ||||
|  | ||||
|     bool has_data(); | ||||
|     bool store(uint32_t num_bytes = 0); | ||||
|     void append(); | ||||
| }; | ||||
|  | ||||
| #define DL_CACHE_SLOTS   250 | ||||
| @@ -0,0 +1,230 @@ | ||||
| /****************** | ||||
|  * event_loop.cpp * | ||||
|  ******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_extended.h" | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
| using namespace FTDI; | ||||
|  | ||||
| enum { | ||||
|   UNPRESSED       = 0x00 | ||||
| }; | ||||
|  | ||||
| tiny_timer_t touch_timer; | ||||
| UIData::flags_t UIData::flags; | ||||
| uint8_t pressed_tag  = UNPRESSED; | ||||
|  | ||||
| uint8_t UIData::get_persistent_data_mask() { | ||||
|   // A bit mask for flags that should be stored to the EEPROM. | ||||
|   // Others are considered temporarily values that need not be | ||||
|   // saved. | ||||
|   constexpr flags_t persistent_flags = { | ||||
|     bits: { | ||||
|       touch_start_sound:  true, | ||||
|       touch_end_sound:    true, | ||||
|       touch_repeat_sound: true, | ||||
|       show_animations:    true | ||||
|     } | ||||
|   }; | ||||
|   return persistent_flags.value; | ||||
| } | ||||
|  | ||||
| void UIData::reset_persistent_data() { | ||||
|   // Default values for persistent data | ||||
|   constexpr flags_t default_flags = { | ||||
|     bits: { | ||||
|       touch_start_sound:  true, | ||||
|       touch_end_sound:    true, | ||||
|       touch_repeat_sound: true, | ||||
|       show_animations:    true, | ||||
|       touch_debouncing:   false, | ||||
|       ignore_unpress:     false | ||||
|     } | ||||
|   }; | ||||
|   flags.value = default_flags.value; | ||||
| } | ||||
|  | ||||
| uint8_t UIData::get_persistent_data() { | ||||
|   return flags.value & get_persistent_data_mask(); | ||||
| } | ||||
|  | ||||
| void UIData::set_persistent_data(uint8_t value) { | ||||
|   flags.value = value & get_persistent_data_mask(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void UIData::enable_touch_sounds(bool enabled) { | ||||
|   UIData::flags.bits.touch_start_sound  = enabled; | ||||
|   UIData::flags.bits.touch_end_sound    = enabled; | ||||
|   UIData::flags.bits.touch_repeat_sound = enabled; | ||||
| } | ||||
|  | ||||
| bool UIData::touch_sounds_enabled() { | ||||
|   return UIData::flags.bits.touch_start_sound || UIData::flags.bits.touch_end_sound || UIData::flags.bits.touch_repeat_sound; | ||||
| } | ||||
|  | ||||
| void UIData::enable_animations(bool enabled) { | ||||
|     UIData::flags.bits.show_animations = enabled; | ||||
| } | ||||
|  | ||||
| bool UIData::animations_enabled() { | ||||
|   return UIData::flags.bits.show_animations; | ||||
| } | ||||
|  | ||||
| namespace FTDI { | ||||
|   uint8_t EventLoop::get_pressed_tag() { | ||||
|     return pressed_tag; | ||||
|   } | ||||
|  | ||||
|   bool EventLoop::is_touch_held() { | ||||
|     return pressed_tag != 0; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * process_events(): Process events from the touch panel. | ||||
|    * | ||||
|    * This function consists of a state machine that accomplishes the following: | ||||
|    * | ||||
|    *  - Reads the tag register from the touch panel | ||||
|    *  - Dispatches onTouchStart and onTouchEnd events to the active screen. | ||||
|    *  - Handles auto-repetition by sending onTouchHeld to the active screen periodically. | ||||
|    *  - Plays touch feedback "click" sounds when appropriate. | ||||
|    *  - Performs debouncing to supress spurious touch events. | ||||
|    * | ||||
|    */ | ||||
|   void EventLoop::process_events() { | ||||
|     // If the LCD is processing commands, don't check | ||||
|     // for tags since they may be changing and could | ||||
|     // cause spurious events. | ||||
|     if (!touch_timer.elapsed(TOUCH_UPDATE_INTERVAL) || CLCD::CommandFifo::is_processing()) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     const uint8_t tag = CLCD::get_tag(); | ||||
|  | ||||
|     switch (pressed_tag) { | ||||
|       case UNPRESSED: | ||||
|         if (tag != 0) { | ||||
|           #ifdef UI_FRAMEWORK_DEBUG | ||||
|             SERIAL_ECHO_START(); | ||||
|             SERIAL_ECHOLNPAIR("Touch start: ", tag); | ||||
|           #endif | ||||
|  | ||||
|           pressed_tag = tag; | ||||
|           current_screen.onRefresh(); | ||||
|  | ||||
|           // When the user taps on a button, activate the onTouchStart handler | ||||
|           const uint8_t lastScreen = current_screen.getScreen(); | ||||
|  | ||||
|           if (current_screen.onTouchStart(tag)) { | ||||
|             touch_timer.start(); | ||||
|             if (UIData::flags.bits.touch_start_sound) sound.play(press_sound); | ||||
|           } | ||||
|  | ||||
|           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. | ||||
|             UIData::flags.bits.ignore_unpress = true; | ||||
|           } else { | ||||
|             UIData::flags.bits.ignore_unpress = false; | ||||
|           } | ||||
|         } else { | ||||
|           touch_timer.start(); | ||||
|         } | ||||
|         break; | ||||
|       default: // PRESSED | ||||
|         if (!UIData::flags.bits.touch_debouncing) { | ||||
|           if (tag == pressed_tag) { | ||||
|             // The user is holding down a button. | ||||
|             if (touch_timer.elapsed(1000 / TOUCH_REPEATS_PER_SECOND) && current_screen.onTouchHeld(tag)) { | ||||
|               current_screen.onRefresh(); | ||||
|               if (UIData::flags.bits.touch_repeat_sound) sound.play(repeat_sound); | ||||
|               touch_timer.start(); | ||||
|             } | ||||
|           } | ||||
|           else if (tag == 0) { | ||||
|             touch_timer.start(); | ||||
|             UIData::flags.bits.touch_debouncing = true; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         else { | ||||
|           // Debouncing... | ||||
|  | ||||
|           if (tag == pressed_tag) { | ||||
|             // If while debouncing, we detect a press, then cancel debouncing. | ||||
|             UIData::flags.bits.touch_debouncing = false; | ||||
|           } | ||||
|  | ||||
|           else if (touch_timer.elapsed(DEBOUNCE_PERIOD)) { | ||||
|             UIData::flags.bits.touch_debouncing = false; | ||||
|  | ||||
|             if (UIData::flags.bits.ignore_unpress) { | ||||
|               UIData::flags.bits.ignore_unpress = false; | ||||
|               pressed_tag = UNPRESSED; | ||||
|               break; | ||||
|             } | ||||
|  | ||||
|             if (UIData::flags.bits.touch_end_sound) sound.play(unpress_sound); | ||||
|  | ||||
|             #ifdef UI_FRAMEWORK_DEBUG | ||||
|               SERIAL_ECHO_START(); | ||||
|               SERIAL_ECHOLNPAIR("Touch end: ", tag); | ||||
|             #endif | ||||
|  | ||||
|             const uint8_t saved_pressed_tag = pressed_tag; | ||||
|             pressed_tag = UNPRESSED; | ||||
|             current_screen.onTouchEnd(saved_pressed_tag); | ||||
|             current_screen.onRefresh(); | ||||
|           } | ||||
|         } | ||||
|         break; | ||||
|     } // switch (pressed_tag) | ||||
|  | ||||
|   } // processEvents() | ||||
|  | ||||
|   void EventLoop::setup() { | ||||
|     CLCD::init(); | ||||
|     DLCache::init(); | ||||
|     UIData::reset_persistent_data(); | ||||
|     current_screen.start(); | ||||
|   } | ||||
|  | ||||
|   void EventLoop::loop() { | ||||
|     sound.onIdle(); | ||||
|  | ||||
|     /** | ||||
|       * Guard against re-entry of UI methods, which can | ||||
|       * crash. Re-entry can happen because some functions | ||||
|       * (e.g. planner.synchronize) call idle(). | ||||
|       */ | ||||
|     if (!UIData::flags.bits.prevent_reentry) { | ||||
|       UIData::flags.bits.prevent_reentry = true; | ||||
|       current_screen.onIdle(); | ||||
|       process_events(); | ||||
|       UIData::flags.bits.prevent_reentry = false; | ||||
|     } | ||||
|   } | ||||
| } // namespace FTDI | ||||
|  | ||||
| #endif // FTDI_EXTENDED | ||||
| @@ -0,0 +1,74 @@ | ||||
| /**************** | ||||
|  * event_loop.h * | ||||
|  ****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #define STATUS_UPDATE_INTERVAL     1000 | ||||
| #define TOUCH_UPDATE_INTERVAL        50 | ||||
| #define TOUCH_REPEATS_PER_SECOND      4 | ||||
| #define DEBOUNCE_PERIOD             150 | ||||
|  | ||||
| class UIData { | ||||
|   private: | ||||
|     typedef union { | ||||
|       struct { | ||||
|         uint8_t touch_start_sound  : 1; | ||||
|         uint8_t touch_end_sound    : 1; | ||||
|         uint8_t touch_repeat_sound : 1; | ||||
|         uint8_t show_animations    : 1; | ||||
|         uint8_t touch_debouncing   : 1; | ||||
|         uint8_t ignore_unpress     : 1; | ||||
|         uint8_t prevent_reentry    : 1; | ||||
|       } bits; | ||||
|       uint8_t value; | ||||
|     } flags_t; | ||||
|  | ||||
|   public: | ||||
|     static flags_t flags; | ||||
|  | ||||
|     static uint8_t get_persistent_data_mask(); | ||||
|     static uint8_t get_persistent_data(); | ||||
|     static void set_persistent_data(uint8_t value); | ||||
|     static void reset_persistent_data(); | ||||
|  | ||||
|     static void enable_touch_sounds(bool enabled); | ||||
|     static bool touch_sounds_enabled(); | ||||
|     static void enable_animations(bool enabled); | ||||
|     static bool animations_enabled(); | ||||
| }; | ||||
|  | ||||
| namespace FTDI { | ||||
|   class EventLoop { | ||||
|     private: | ||||
|       static constexpr FTDI::effect_t press_sound   = FTDI::CHACK; | ||||
|       static constexpr FTDI::effect_t repeat_sound  = FTDI::CHACK; | ||||
|       static constexpr FTDI::effect_t unpress_sound = FTDI::POP; | ||||
|       static void process_events(); | ||||
|  | ||||
|     public: | ||||
|       static void setup(); | ||||
|       static void loop(); | ||||
|  | ||||
|       static uint8_t get_pressed_tag(); | ||||
|       static bool is_touch_held(); | ||||
|   }; | ||||
| } | ||||
| @@ -0,0 +1,45 @@ | ||||
| /******************* | ||||
|  * ftdi_extended.h * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2019 - Aleph Objects, Inc.                  * | ||||
|  *   Written By Marcio Teixeira 201( - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../compat.h" | ||||
| #include "../basic/ftdi_basic.h" | ||||
|  | ||||
| #if !defined(__MARLIN_FIRMWARE__) | ||||
|   #define FTDI_EXTENDED | ||||
| #endif | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
|   #include "rgb_t.h" | ||||
|   #include "bitmap_info.h" | ||||
|   #include "tiny_timer.h" | ||||
|   #include "grid_layout.h" | ||||
|   #include "dl_cache.h" | ||||
|   #include "screen_types.h" | ||||
|   #include "event_loop.h" | ||||
|   #include "command_processor.h" | ||||
|   #include "sound_player.h" | ||||
|   #include "sound_list.h" | ||||
|   #include "polygon.h" | ||||
|   #include "text_box.h" | ||||
| #endif | ||||
| @@ -0,0 +1,98 @@ | ||||
| /***************** | ||||
|  * grid_layout.h * | ||||
|  *****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /* 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 | ||||
|  | ||||
| #ifdef TOUCH_UI_800x480 | ||||
|   #define MARGIN_L         5 | ||||
|   #define MARGIN_R         5 | ||||
|   #define MARGIN_T         5 | ||||
|   #define MARGIN_B         5 | ||||
|   #define MARGIN_DEFAULT   5 | ||||
| #else | ||||
|   #define MARGIN_L         3 | ||||
|   #define MARGIN_R         3 | ||||
|   #define MARGIN_T         3 | ||||
|   #define MARGIN_B         3 | ||||
|   #define MARGIN_DEFAULT   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. | ||||
| #define GRID_X(x)        ((x)*(FTDI::display_width-EDGE_R)/GRID_COLS) | ||||
| #define GRID_Y(y)        ((y)*FTDI::display_height/GRID_ROWS) | ||||
|  | ||||
| // 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) | ||||
|  | ||||
| // Draw a reference grid for ease of spacing out widgets. | ||||
| #define DRAW_LAYOUT_GRID \ | ||||
|   { \ | ||||
|     cmd.cmd(LINE_WIDTH(4)); \ | ||||
|     for(int i = 1; i <= GRID_COLS; i++) { \ | ||||
|       cmd.cmd(BEGIN(LINES)); \ | ||||
|       cmd.cmd(VERTEX2F(GRID_X(i) *16, 0             *16)); \ | ||||
|       cmd.cmd(VERTEX2F(GRID_X(i) *16, FTDI::display_height *16)); \ | ||||
|     } \ | ||||
|     for(int i = 1; i < GRID_ROWS; i++) { \ | ||||
|       cmd.cmd(BEGIN(LINES)); \ | ||||
|       cmd.cmd(VERTEX2F(0                       *16, GRID_Y(i) *16)); \ | ||||
|       cmd.cmd(VERTEX2F(FTDI::display_width     *16, GRID_Y(i) *16)); \ | ||||
|     } \ | ||||
|     cmd.cmd(LINE_WIDTH(16)); \ | ||||
|   } | ||||
|  | ||||
| namespace FTDI { | ||||
|   #ifdef TOUCH_UI_PORTRAIT | ||||
|     constexpr uint16_t display_width  = Vsize; | ||||
|     constexpr uint16_t display_height = Hsize; | ||||
|   #else | ||||
|     constexpr uint16_t display_width  = Hsize; | ||||
|     constexpr uint16_t display_height = Vsize; | ||||
|   #endif | ||||
| } | ||||
| @@ -0,0 +1,96 @@ | ||||
| /************* | ||||
|  * polygon.h * | ||||
|  *************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /** | ||||
|  * The Polygon class helps drawing filled or stroked polygons on the FTDI EVE: | ||||
|  * | ||||
|  *   CommandProcessor cmd; | ||||
|  *   cmd.cmd(COLOR_RGB(0x00FF00)); | ||||
|  * | ||||
|  *   Polygon p(cmd); | ||||
|  *   p.begin_fill(); | ||||
|  *     p.begin_loop(); | ||||
|  *      p(10,10); | ||||
|  *      p(20,10); | ||||
|  *      p(20,20); | ||||
|  *      p(10,20); | ||||
|  *     p.end_loop(); | ||||
|  *     p.begin_loop(); | ||||
|  *        ...  // Additional closed paths | ||||
|  *     p.end_loop(); | ||||
|  *        ... | ||||
|  *   p.end_fill(); | ||||
|  * | ||||
|  * Based on the example from "Applicaton Note AN_334, FT801 Polygon Application": | ||||
|  * | ||||
|  *   https://brtchip.com/wp-content/uploads/Support/Documentation/Application_Notes/ICs/EVE/AN_334-FT801_Polygon_Application.pdf | ||||
|  */ | ||||
|  | ||||
| namespace FTDI { | ||||
|   class Polygon { | ||||
|     private: | ||||
|       FTDI::begin_t path_initiator = FTDI::LINE_STRIP; | ||||
|  | ||||
|     public: | ||||
|       CommandProcessor &cmd; | ||||
|  | ||||
|       Polygon(CommandProcessor &c) : cmd(c) {} | ||||
|  | ||||
|       void begin_fill() { | ||||
|         using namespace FTDI; | ||||
|         cmd.cmd(SAVE_CONTEXT()); | ||||
|         cmd.cmd(TAG_MASK(0)); | ||||
|         cmd.cmd(CLEAR(0,1,0)); | ||||
|         cmd.cmd(COLOR_MASK(0,0,0,0)); | ||||
|         cmd.cmd(STENCIL_OP(STENCIL_OP_KEEP, STENCIL_OP_INVERT)); | ||||
|         cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_ALWAYS, 255, 255)); | ||||
|         // Drawing the edge strip along scan lines | ||||
|         // seems to yield the best performance | ||||
|         #ifdef TOUCH_UI_PORTRAIT | ||||
|           path_initiator = EDGE_STRIP_B; | ||||
|         #else | ||||
|           path_initiator = EDGE_STRIP_R; | ||||
|         #endif | ||||
|       } | ||||
|  | ||||
|       // Specify a clipping rectangle to paint fewer pixels and reduce rendering time, otherwise all pixels will be painted. | ||||
|       void end_fill(const int16_t x1 = 0, const int16_t y1 = 0, const int16_t x2 = display_width * 16, const int16_t y2 = display_height * 16) { | ||||
|         using namespace FTDI; | ||||
|         cmd.cmd(RESTORE_CONTEXT()); | ||||
|  | ||||
|         cmd.cmd(SAVE_CONTEXT()); | ||||
|         cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_NOTEQUAL, 0, 255)); | ||||
|         cmd.cmd(BEGIN(RECTS)); | ||||
|         cmd.cmd(VERTEX2F(x1, y1)); | ||||
|         cmd.cmd(VERTEX2F(x2, y2)); | ||||
|         cmd.cmd(RESTORE_CONTEXT()); | ||||
|       } | ||||
|  | ||||
|       void begin_stroke() {path_initiator = FTDI::LINE_STRIP;} | ||||
|       void begin_loop()   {cmd.cmd(FTDI::BEGIN(path_initiator));} | ||||
|       void end_stroke()   {} | ||||
|       void end_loop()     {} | ||||
|  | ||||
|       void operator()(const uint16_t x, const uint16_t y) {cmd.cmd(FTDI::VERTEX2F(x, y));} | ||||
|   }; | ||||
| } | ||||
| @@ -0,0 +1,44 @@ | ||||
| /*********** | ||||
|  * rgb_t.h * | ||||
|  ***********/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| struct rgb_t { | ||||
|     union { | ||||
|       struct { | ||||
|         uint8_t  b,g,r,a; | ||||
|       }; | ||||
|       uint32_t packed; | ||||
|     }; | ||||
|  | ||||
|     rgb_t()                                : packed(0)              {} | ||||
|     rgb_t(uint32_t rgb)                    : packed(rgb)            {} | ||||
|     rgb_t(uint8_t r, uint8_t g, uint8_t b) : b(b), g(g), r(r), a(0) {} | ||||
|     operator uint32_t() const              {return packed;}; | ||||
|  | ||||
|     static void lerp(float t, const rgb_t a, const rgb_t b, rgb_t &c) { | ||||
|       c.r = a.r + t * (b.r - a.r); | ||||
|       c.g = a.g + t * (b.g - a.g); | ||||
|       c.b = a.b + t * (b.b - a.b); | ||||
|     } | ||||
|  | ||||
|     uint8_t luminance() const {return 0.299*r + 0.587*g + 0.114*b;} | ||||
| }; | ||||
| @@ -0,0 +1,106 @@ | ||||
| /****************** | ||||
|  * screen_types.h * | ||||
|  ******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_extended.h" | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
|  | ||||
| /********************** VIRTUAL DISPATCH DATA TYPE  ******************************/ | ||||
|  | ||||
| uint8_t ScreenRef::lookupScreen(onRedraw_func_t onRedraw_ptr) { | ||||
|   for(uint8_t type = 0; type < functionTableSize; type++) { | ||||
|     if (GET_METHOD(type, onRedraw) == onRedraw_ptr) { | ||||
|       return type; | ||||
|     } | ||||
|   } | ||||
|   #ifdef UI_FRAMEWORK_DEBUG | ||||
|     SERIAL_ECHO_START(); | ||||
|     SERIAL_ECHOPAIR("Screen not found: ", (uintptr_t) onRedraw_ptr); | ||||
|   #endif | ||||
|   return 0xFF; | ||||
| } | ||||
|  | ||||
| void ScreenRef::setScreen(onRedraw_func_t onRedraw_ptr) { | ||||
|   uint8_t type = lookupScreen(onRedraw_ptr); | ||||
|   if (type != 0xFF) { | ||||
|     setType(type); | ||||
|     #ifdef UI_FRAMEWORK_DEBUG | ||||
|       SERIAL_ECHO_START(); | ||||
|       SERIAL_ECHOLNPAIR("New screen: ", type); | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| void ScreenRef::initializeAll() { | ||||
|   for(uint8_t type = 0; type < functionTableSize; type++) { | ||||
|     GET_METHOD(type, onStartup)(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /********************** SCREEN STACK  ******************************/ | ||||
|  | ||||
| void ScreenStack::start() { | ||||
|   initializeAll(); | ||||
|   onEntry(); | ||||
| } | ||||
|  | ||||
| void ScreenStack::push(onRedraw_func_t onRedraw_ptr) { | ||||
|   stack[3] = stack[2]; | ||||
|   stack[2] = stack[1]; | ||||
|   stack[1] = stack[0]; | ||||
|   stack[0] = lookupScreen(onRedraw_ptr); | ||||
| } | ||||
|  | ||||
| void ScreenStack::push() { | ||||
|   stack[3] = stack[2]; | ||||
|   stack[2] = stack[1]; | ||||
|   stack[1] = stack[0]; | ||||
|   stack[0] = getType(); | ||||
| } | ||||
|  | ||||
| void ScreenStack::pop() { | ||||
|   setType(stack[0]); | ||||
|   forget(); | ||||
| } | ||||
|  | ||||
| void ScreenStack::forget() { | ||||
|   stack[0] = stack[1]; | ||||
|   stack[1] = stack[2]; | ||||
|   stack[2] = stack[3]; | ||||
|   stack[3] = 0; | ||||
| } | ||||
|  | ||||
| void ScreenStack::goTo(onRedraw_func_t s) { | ||||
|   push(); | ||||
|   onExit(); | ||||
|   setScreen(s); | ||||
|   onEntry(); | ||||
| } | ||||
|  | ||||
| void ScreenStack::goBack() { | ||||
|   onExit(); | ||||
|   pop(); | ||||
|   onEntry(); | ||||
| } | ||||
|  | ||||
| ScreenStack current_screen; | ||||
|  | ||||
| #endif // FTDI_EXTENDED | ||||
| @@ -0,0 +1,215 @@ | ||||
| /******************** | ||||
|  * screen_types.cpp * | ||||
|  ********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| typedef enum { | ||||
|   BACKGROUND  = 1, | ||||
|   FOREGROUND  = 2, | ||||
|   BOTH        = 3 | ||||
| } draw_mode_t; | ||||
|  | ||||
|  /********************** 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::onRedraw, \ | ||||
|   className::onTouchStart, \ | ||||
|   className::onTouchHeld, \ | ||||
|   className::onTouchEnd \ | ||||
| } | ||||
|  | ||||
| #define GET_METHOD(type, method) reinterpret_cast<method##_func_t*>(pgm_read_ptr_far(&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 onRedraw_func_t(draw_mode_t); | ||||
|     typedef bool onTouchStart_func_t(uint8_t); | ||||
|     typedef bool onTouchHeld_func_t(uint8_t); | ||||
|     typedef bool 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; | ||||
|       onRedraw_func_t      *onRedraw_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; | ||||
|     } | ||||
|  | ||||
|     uint8_t lookupScreen(onRedraw_func_t onRedraw_ptr); | ||||
|  | ||||
|     void setScreen(onRedraw_func_t onRedraw_ptr); | ||||
|  | ||||
|     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 onRedraw(draw_mode_t dm)  {GET_METHOD(type, onRedraw)(dm);} | ||||
|     bool onTouchStart(uint8_t tag) {return GET_METHOD(type, onTouchStart)(tag);} | ||||
|     bool onTouchHeld(uint8_t tag)  {return GET_METHOD(type, onTouchHeld)(tag);} | ||||
|     bool onTouchEnd(uint8_t tag)   {return GET_METHOD(type, onTouchEnd)(tag);} | ||||
|  | ||||
|     void initializeAll(); | ||||
| }; | ||||
|  | ||||
| /********************** 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(); | ||||
|     void push(onRedraw_func_t); | ||||
|     void push(); | ||||
|     void pop(); | ||||
|     void forget(); | ||||
|     void goTo(onRedraw_func_t); | ||||
|     void goBack(); | ||||
|  | ||||
|     uint8_t peek()      {return stack[0];} | ||||
|     uint8_t getScreen() {return getType();} | ||||
| }; | ||||
|  | ||||
| extern ScreenStack current_screen; | ||||
|  | ||||
| /********************** BASE SCREEN CLASS ******************************/ | ||||
|  | ||||
| /* 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 bool onTouchStart(uint8_t)  {return true;} | ||||
|     static bool onTouchHeld(uint8_t)   {return false;} | ||||
|     static bool onTouchEnd(uint8_t)    {return true;} | ||||
| }; | ||||
|  | ||||
| #define PUSH_SCREEN(screen)   current_screen.push(screen::onRedraw); | ||||
| #define GOTO_SCREEN(screen)   current_screen.goTo(screen::onRedraw); | ||||
| #define GOTO_PREVIOUS()       current_screen.goBack(); | ||||
| #define AT_SCREEN(screen)     (current_screen.getType() == current_screen.lookupScreen(screen::onRedraw)) | ||||
| #define IS_PARENT_SCREEN(screen) (current_screen.peek() == current_screen.lookupScreen(screen::onRedraw)) | ||||
|  | ||||
| /************************** CACHED VS UNCHACHED SCREENS ***************************/ | ||||
|  | ||||
| class UncachedScreen { | ||||
|   public: | ||||
|     static void onRefresh() { | ||||
|       using namespace FTDI; | ||||
|       CLCD::CommandFifo cmd; | ||||
|       cmd.cmd(CMD_DLSTART); | ||||
|  | ||||
|       current_screen.onRedraw(BOTH); | ||||
|  | ||||
|       cmd.cmd(DL::DL_DISPLAY); | ||||
|       cmd.cmd(CMD_SWAP); | ||||
|       cmd.execute(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template<uint8_t DL_SLOT,uint32_t DL_SIZE = 0> | ||||
| class CachedScreen { | ||||
|   protected: | ||||
|     static bool storeBackground(){ | ||||
|       DLCache dlcache(DL_SLOT); | ||||
|       if (!dlcache.store(DL_SIZE)) { | ||||
|         SERIAL_ECHO_START(); | ||||
|         SERIAL_ECHOLNPGM("CachedScreen::storeBackground() failed: not enough DL cache space"); | ||||
|         return false; | ||||
|       } | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     static void repaintBackground(){ | ||||
|       using namespace FTDI; | ||||
|       DLCache dlcache(DL_SLOT); | ||||
|       CLCD::CommandFifo cmd; | ||||
|  | ||||
|       cmd.cmd(CMD_DLSTART); | ||||
|       current_screen.onRedraw(BACKGROUND); | ||||
|  | ||||
|       dlcache.store(DL_SIZE); | ||||
|     } | ||||
|  | ||||
|   public: | ||||
|     static void onRefresh(){ | ||||
|       using namespace FTDI; | ||||
|       DLCache dlcache(DL_SLOT); | ||||
|       CLCD::CommandFifo cmd; | ||||
|  | ||||
|       cmd.cmd(CMD_DLSTART); | ||||
|  | ||||
|       if (dlcache.has_data()) { | ||||
|         dlcache.append(); | ||||
|       } else { | ||||
|         current_screen.onRedraw(BACKGROUND); | ||||
|         dlcache.store(DL_SIZE); | ||||
|       } | ||||
|  | ||||
|       current_screen.onRedraw(FOREGROUND); | ||||
|  | ||||
|       cmd.cmd(DL::DL_DISPLAY); | ||||
|       cmd.cmd(CMD_SWAP); | ||||
|       cmd.execute(); | ||||
|     } | ||||
| }; | ||||
| @@ -0,0 +1,38 @@ | ||||
| /**************** | ||||
|  * sound_list.h * | ||||
|  ****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| class SoundList { | ||||
|   private: | ||||
|     static PROGMEM const struct list_t { | ||||
|       const char *const PROGMEM name; | ||||
|       const FTDI::SoundPlayer::sound_t* data; | ||||
|     } list[]; | ||||
|   public: | ||||
|     static const uint8_t n; | ||||
|     static inline const char* name(uint8_t val) { | ||||
|       return (const char* ) pgm_read_ptr_near(&list[val].name); | ||||
|     } | ||||
|     static inline FTDI::SoundPlayer::sound_t* data(uint8_t val) { | ||||
|       return (FTDI::SoundPlayer::sound_t*) pgm_read_ptr_near(&list[val].data); | ||||
|     } | ||||
| }; | ||||
| @@ -0,0 +1,111 @@ | ||||
| /******************** | ||||
|  * sound_player.cpp * | ||||
|  ********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_extended.h" | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
|  | ||||
| namespace FTDI { | ||||
|   SoundPlayer sound; // Global sound player object | ||||
|  | ||||
|   void SoundPlayer::set_volume(uint8_t vol) { | ||||
|     CLCD::mem_write_8(REG::VOL_SOUND, vol); | ||||
|   } | ||||
|  | ||||
|   uint8_t SoundPlayer::get_volume() { | ||||
|     return CLCD::mem_read_8(REG::VOL_SOUND); | ||||
|   } | ||||
|  | ||||
|   void SoundPlayer::play(effect_t effect, note_t note) { | ||||
|  | ||||
|     #ifdef UI_FRAMEWORK_DEBUG | ||||
|       SERIAL_ECHO_START(); | ||||
|       SERIAL_ECHOPAIR("Playing note ", note); | ||||
|       SERIAL_ECHOLNPAIR(", instrument ", effect); | ||||
|     #endif | ||||
|  | ||||
|     // Play the note | ||||
|     CLCD::mem_write_16(REG::SOUND, (note == REST) ? 0 : (((note ? note : NOTE_C4) << 8) | effect)); | ||||
|     CLCD::mem_write_8(REG::PLAY, 1); | ||||
|   } | ||||
|  | ||||
|   note_t SoundPlayer::frequency_to_midi_note(const uint16_t frequency_hz) { | ||||
|     const float f0 = 440; | ||||
|     return note_t(NOTE_A4 + (log(frequency_hz)-log(f0))*12/log(2) + 0.5); | ||||
|   } | ||||
|  | ||||
|   // Plays a tone of a given frequency and duration. Since the FTDI FT810 only | ||||
|   // supports MIDI notes, we round down to the nearest note. | ||||
|  | ||||
|   void SoundPlayer::play_tone(const uint16_t frequency_hz, const uint16_t duration_ms) { | ||||
|     play(ORGAN, frequency_to_midi_note(frequency_hz)); | ||||
|  | ||||
|     // Schedule silence to squelch the note after the duration expires. | ||||
|     sequence = silence; | ||||
|     wait = duration_ms; | ||||
|     timer.start(); | ||||
|   } | ||||
|  | ||||
|   void SoundPlayer::play(const sound_t* seq, play_mode_t mode) { | ||||
|     sequence = seq; | ||||
|     wait     = 250; // Adding this delay causes the note to not be clipped, not sure why. | ||||
|     timer.start(); | ||||
|  | ||||
|     if (mode == PLAY_ASYNCHRONOUS) return; | ||||
|  | ||||
|     // If playing synchronously, then play all the notes here | ||||
|  | ||||
|     while (has_more_notes()) { | ||||
|       onIdle(); | ||||
|       #ifdef EXTENSIBLE_UI | ||||
|         ExtUI::yield(); | ||||
|       #endif | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   bool SoundPlayer::is_sound_playing() { | ||||
|     return CLCD::mem_read_8( REG::PLAY ) & 0x1; | ||||
|   } | ||||
|  | ||||
|   void SoundPlayer::onIdle() { | ||||
|     if (!sequence) return; | ||||
|  | ||||
|     const bool ready_for_next_note = (wait == 0) ? !is_sound_playing() : timer.elapsed(wait); | ||||
|  | ||||
|     if (ready_for_next_note) { | ||||
|       const effect_t fx = effect_t(pgm_read_byte(&sequence->effect)); | ||||
|       const note_t   nt =   note_t(pgm_read_byte(&sequence->note)); | ||||
|       const uint32_t ms = uint32_t(pgm_read_byte(&sequence->sixteenths)) * 1000 / 16; | ||||
|  | ||||
|       if (ms == 0 && fx == SILENCE && nt == END_SONG) { | ||||
|         sequence = 0; | ||||
|         play(SILENCE, REST); | ||||
|       } else { | ||||
|         wait = ms; | ||||
|         timer.start(); | ||||
|         play(fx, nt); | ||||
|         sequence++; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } // namespace FTDI | ||||
|  | ||||
| #endif // FTDI_EXTENDED | ||||
| @@ -0,0 +1,70 @@ | ||||
| /****************** | ||||
|  * sound_player.h * | ||||
|  ******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace FTDI { | ||||
|   typedef enum { | ||||
|     PLAY_ASYNCHRONOUS, | ||||
|     PLAY_SYNCHRONOUS | ||||
|   } play_mode_t; | ||||
|  | ||||
|   class SoundPlayer { | ||||
|     typedef FTDI::ftdi_registers  REG; | ||||
|     typedef FTDI::ftdi_memory_map MAP; | ||||
|  | ||||
|     public: | ||||
|       struct sound_t { | ||||
|         effect_t  effect;      // The sound effect number | ||||
|         note_t    note;        // The MIDI note value | ||||
|         uint16_t  sixteenths;  // Duration of note, in sixteeths of a second, or zero to play to completion | ||||
|       }; | ||||
|  | ||||
|       const uint8_t WAIT = 0; | ||||
|  | ||||
|     private: | ||||
|       const sound_t   *sequence; | ||||
|       tiny_timer_t     timer; | ||||
|       tiny_time_t      wait; | ||||
|  | ||||
|       note_t frequency_to_midi_note(const uint16_t frequency); | ||||
|  | ||||
|     public: | ||||
|       static void set_volume(uint8_t volume); | ||||
|       static uint8_t get_volume(); | ||||
|  | ||||
|       static void play(effect_t effect, note_t note = NOTE_C4); | ||||
|       static bool is_sound_playing(); | ||||
|  | ||||
|       void play(const sound_t* seq, play_mode_t mode = PLAY_SYNCHRONOUS); | ||||
|       void play_tone(const uint16_t frequency_hz, const uint16_t duration_ms); | ||||
|       bool has_more_notes() {return sequence != 0;}; | ||||
|  | ||||
|       void onIdle(); | ||||
|   }; | ||||
|  | ||||
|   extern SoundPlayer sound; | ||||
|  | ||||
|   const PROGMEM SoundPlayer::sound_t silence[] = { | ||||
|     {SILENCE,      END_SONG, 0} | ||||
|   }; | ||||
| } | ||||
| @@ -0,0 +1,129 @@ | ||||
| /**************** | ||||
|  * text_box.cpp * | ||||
|  ****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_extended.h" | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
|  | ||||
| namespace FTDI { | ||||
|   /** | ||||
|    * Given a str, end will be set to the position at which a line needs to | ||||
|    * be broken so that the display width is less than w. The line will also | ||||
|    * be broken after a '\n'. Returns the display width of the line. | ||||
|    */ | ||||
|   static uint16_t find_line_break(const CLCD::FontMetrics &fm, uint16_t w, const char *str, const char *&end) { | ||||
|     const char *p = str; | ||||
|     end = str + strlen(str); | ||||
|     uint16_t width = fm.get_text_width(str); | ||||
|     for(;;) { | ||||
|       // Find next tentative line break. | ||||
|       char delim = *(p); | ||||
|       while (delim && delim != ' ' && delim != '\n') { | ||||
|         delim = *(++p); | ||||
|       } | ||||
|       // Check to see whether to break the line. | ||||
|       const uint16_t margin = fm.get_text_width("  "); | ||||
|       const uint16_t lw = p > str ? fm.get_text_width(str, p - str) + margin : 0; | ||||
|       if (lw < w) { | ||||
|         width = lw; | ||||
|         switch (delim) { | ||||
|           case '\0': | ||||
|             end = p; | ||||
|             break; | ||||
|           case '\n': | ||||
|             end = ++p; | ||||
|             break; | ||||
|           case ' ': | ||||
|             end = ++p; | ||||
|             continue; | ||||
|         } | ||||
|       } | ||||
|       return width; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This function returns a measurements of the word-wrapped text box. | ||||
|    */ | ||||
|   static void measure_text_box(const CLCD::FontMetrics &fm, const char *str, uint16_t &width, uint16_t &height) { | ||||
|     const char *line_start = (const char*)str; | ||||
|     const char *line_end; | ||||
|     const uint16_t wrap_width = width; | ||||
|     width = height = 0; | ||||
|     for(;;) { | ||||
|       uint16_t line_width = find_line_break(fm, wrap_width, line_start, line_end); | ||||
|       if (line_end == line_start) break; | ||||
|       width  = max(width, line_width); | ||||
|       height += fm.height; | ||||
|       line_start = line_end; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * This function draws text inside a bounding box, doing word wrapping and using the largest font that will fit. | ||||
|    */ | ||||
|   void draw_text_box(CommandProcessor& cmd, int x, int y, int w, int h, const char *str, uint16_t options, uint8_t font) { | ||||
|     CLCD::FontMetrics fm(font); | ||||
|  | ||||
|     uint16_t box_width, box_height; | ||||
|  | ||||
|     for(;;) { | ||||
|       box_width = w; | ||||
|       measure_text_box(fm, str, box_width, box_height); | ||||
|       if (box_width <= (uint16_t)w && box_height <= (uint16_t)h) break; | ||||
|       fm.load(--font); | ||||
|       if (font == 26) break; | ||||
|     } | ||||
|  | ||||
|     const uint16_t dx = (options & OPT_RIGHTX) ? w : (options & OPT_CENTERX) ? w/2 : 0; | ||||
|     const uint16_t dy = (options & OPT_CENTERY) ? (h - box_height)/2 : 0; | ||||
|  | ||||
|     const char *line_start = str; | ||||
|     const char *line_end; | ||||
|     for(;;) { | ||||
|       find_line_break(fm, w, line_start, line_end); | ||||
|       if (line_end == line_start) break; | ||||
|  | ||||
|       const size_t line_len = line_end - line_start; | ||||
|       if (line_len) { | ||||
|         char line[line_len + 1]; | ||||
|         strncpy(line, line_start, line_len); | ||||
|         line[line_len] = 0; | ||||
|         if (line[line_len - 1] == '\n' || line[line_len - 1] == ' ') | ||||
|           line[line_len - 1] = 0; | ||||
|  | ||||
|         cmd.CLCD::CommandFifo::text(x + dx, y + dy, font, options & ~OPT_CENTERY); | ||||
|         cmd.CLCD::CommandFifo::str(line); | ||||
|       } | ||||
|       y += fm.height; | ||||
|  | ||||
|       line_start = line_end; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void draw_text_box(CommandProcessor& cmd, int x, int y, int w, int h, progmem_str pstr, uint16_t options, uint8_t font) { | ||||
|     char str[strlen_P((const char*)pstr) + 1]; | ||||
|     strcpy_P(str, (const char*)pstr); | ||||
|     draw_text_box(cmd, x, y, w, h, (const char*) str, options, font); | ||||
|   } | ||||
| } // namespace FTDI | ||||
|  | ||||
| #endif // FTDI_EXTENDED | ||||
| @@ -0,0 +1,30 @@ | ||||
| /************** | ||||
|  * text_box.h * | ||||
|  **************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /** | ||||
|  * This function draws text inside a bounding box, doing word wrapping and using the largest font that will fit. | ||||
|  */ | ||||
| namespace FTDI { | ||||
|   void draw_text_box(class CommandProcessor& cmd, int x, int y, int w, int h, progmem_str str, uint16_t options = 0, uint8_t font = 31); | ||||
|   void draw_text_box(class CommandProcessor& cmd, int x, int y, int w, int h, const char *str, uint16_t options = 0, uint8_t font = 31); | ||||
| } | ||||
| @@ -0,0 +1,51 @@ | ||||
| /****************** | ||||
|  * tiny_timer.cpp * | ||||
|  ******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "ftdi_extended.h" | ||||
|  | ||||
| #ifdef FTDI_EXTENDED | ||||
|  | ||||
| bool tiny_timer_t::elapsed(tiny_time_t duration) { | ||||
|   uint8_t now = tiny_time_t::tiny_time( | ||||
|     #ifdef __MARLIN_FIRMWARE__ | ||||
|       ExtUI::safe_millis() | ||||
|     #else | ||||
|       millis() | ||||
|     #endif | ||||
|   ); | ||||
|   uint8_t elapsed = now - _start; | ||||
|   if (elapsed >= duration._duration) { | ||||
|     return true; | ||||
|   } else { | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void tiny_timer_t::start() { | ||||
|   _start = tiny_time_t::tiny_time( | ||||
|     #ifdef __MARLIN_FIRMWARE__ | ||||
|       ExtUI::safe_millis() | ||||
|     #else | ||||
|       millis() | ||||
|     #endif | ||||
|   ); | ||||
| } | ||||
| #endif // FTDI_EXTENDED | ||||
| @@ -0,0 +1,56 @@ | ||||
| /**************** | ||||
|  * tiny_timer.h * | ||||
|  ****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /* Helpful Reference: | ||||
|  * | ||||
|  *  https://arduino.stackexchange.com/questions/12587/how-can-i-handle-the-millis-rollover | ||||
|  */ | ||||
|  | ||||
| /* tiny_interval_t downsamples a 32-bit millis() value | ||||
|    into a 8-bit value which can record periods of | ||||
|    a few seconds with a rougly 1/16th of second | ||||
|    resolution. This allows us to measure small | ||||
|    intervals without needing to use four-byte counters. | ||||
|  */ | ||||
| class tiny_time_t { | ||||
|   private: | ||||
|     friend class tiny_timer_t; | ||||
|     uint8_t _duration; | ||||
|  | ||||
|     static uint8_t tiny_time(uint32_t ms) {return ceil(float(ms) / 64);}; | ||||
|  | ||||
|   public: | ||||
|     tiny_time_t()            : _duration(0) {} | ||||
|     tiny_time_t(uint32_t ms) : _duration(tiny_time(ms)) {} | ||||
|     tiny_time_t & operator=   (uint32_t ms) {_duration = tiny_time(ms); return *this;} | ||||
|     bool          operator == (uint32_t ms) {return _duration == tiny_time(ms);} | ||||
| }; | ||||
|  | ||||
| class tiny_timer_t { | ||||
|   private: | ||||
|     uint8_t _start; | ||||
|  | ||||
|   public: | ||||
|     void start(); | ||||
|     bool elapsed(tiny_time_t interval); | ||||
| }; | ||||
| @@ -0,0 +1,100 @@ | ||||
| /*********************** | ||||
|  * circular_progress.h * | ||||
|  ***********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /* This function draws a circular progress "ring" */ | ||||
|  | ||||
| void draw_circular_progress(CommandProcessor& cmd, int x, int y, int w, int h, uint8_t percent, uint32_t bgcolor, uint32_t fgcolor, float rim = 0.3) { | ||||
|   using namespace FTDI; | ||||
|  | ||||
|   const float a  = float(percent)/100.0*2.0*PI; | ||||
|   const float a1 = min(PI/2, a); | ||||
|   const float a2 = min(PI/2, a-a1); | ||||
|   const float a3 = min(PI/2, a-a1-a2); | ||||
|   const float a4 = min(PI/2, a-a1-a2-a3); | ||||
|  | ||||
|   const int ro  = min(w,h) * 8; | ||||
|   const int rr = ro * rim; | ||||
|   const int cx = x * 16 + w * 8; | ||||
|   const int cy = y * 16 + h * 8; | ||||
|  | ||||
|   // Load a rim shape into stencil buffer | ||||
|   cmd.cmd(SAVE_CONTEXT()); | ||||
|   cmd.cmd(TAG_MASK(0)); | ||||
|   cmd.cmd(CLEAR(0,1,0)); | ||||
|   cmd.cmd(COLOR_MASK(0,0,0,0)); | ||||
|   cmd.cmd(STENCIL_OP(STENCIL_OP_KEEP, STENCIL_OP_INVERT)); | ||||
|   cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_ALWAYS, 255, 255)); | ||||
|   cmd.cmd(BEGIN(POINTS)); | ||||
|   cmd.cmd(POINT_SIZE(ro)); | ||||
|   cmd.cmd(VERTEX2F(cx, cy)); | ||||
|   cmd.cmd(POINT_SIZE(ro - rr)); | ||||
|   cmd.cmd(VERTEX2F(cx, cy)); | ||||
|   cmd.cmd(RESTORE_CONTEXT()); | ||||
|  | ||||
|   // Mask further drawing by stencil buffer | ||||
|   cmd.cmd(SAVE_CONTEXT()); | ||||
|   cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_NOTEQUAL, 0, 255)); | ||||
|  | ||||
|   // Fill the background | ||||
|   cmd.cmd(COLOR_RGB(bgcolor)); | ||||
|   cmd.cmd(BEGIN(POINTS)); | ||||
|   cmd.cmd(POINT_SIZE(ro)); | ||||
|   cmd.cmd(VERTEX2F(cx, cy)); | ||||
|   cmd.cmd(COLOR_RGB(fgcolor)); | ||||
|  | ||||
|   // Paint upper-right quadrant | ||||
|   cmd.cmd(BEGIN(EDGE_STRIP_A)); | ||||
|   cmd.cmd(VERTEX2F(cx, cy)); | ||||
|   cmd.cmd(VERTEX2F(cx + ro*sin(a1) + 16,cy - ro*cos(a1) + 8)); | ||||
|  | ||||
|   // Paint lower-right quadrant | ||||
|   if (a > PI/2) { | ||||
|     cmd.cmd(BEGIN(EDGE_STRIP_R)); | ||||
|     cmd.cmd(VERTEX2F(cx, cy)); | ||||
|     cmd.cmd(VERTEX2F(cx + ro*cos(a2),cy + ro*sin(a2) + 16)); | ||||
|   } | ||||
|  | ||||
|   // Paint lower-left quadrant | ||||
|   if (a > PI) { | ||||
|     cmd.cmd(BEGIN(EDGE_STRIP_B)); | ||||
|     cmd.cmd(VERTEX2F(cx, cy)); | ||||
|     cmd.cmd(VERTEX2F(cx - ro*sin(a3) - 8,cy + ro*cos(a3))); | ||||
|   } | ||||
|  | ||||
|   // Paint upper-left quadrant | ||||
|   if (a > 1.5*PI) { | ||||
|     cmd.cmd(BEGIN(EDGE_STRIP_L)); | ||||
|     cmd.cmd(VERTEX2F(cx, cy)); | ||||
|     cmd.cmd(VERTEX2F(cx - ro*cos(a4),cy - ro*sin(a4))); | ||||
|   } | ||||
|   cmd.cmd(RESTORE_CONTEXT()); | ||||
|  | ||||
|   // Draw the text | ||||
|   char str[5]; | ||||
|   sprintf(str,"%d\%%",percent); | ||||
|  | ||||
|   cmd.cmd(SAVE_CONTEXT()); | ||||
|   cmd.cmd(COLOR_RGB(fgcolor)); | ||||
|   cmd.text(x,y,w,h,str, OPT_CENTERX | OPT_CENTERY); | ||||
|   cmd.cmd(RESTORE_CONTEXT()); | ||||
| } | ||||
| @@ -0,0 +1,395 @@ | ||||
| /************* | ||||
|  * poly_ui.h * | ||||
|  *************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /** | ||||
|  * The PolyReader class iterates over an array of (x,y) pairs. | ||||
|  * For supporting polygons with holes an end-of-loop marker may | ||||
|  * be embedded into the data stream: | ||||
|  * | ||||
|  *   const PROGMEM uint16_t data[] = { | ||||
|  *      x, y, x, y, ..., eol, | ||||
|  *          ... | ||||
|  *      x, y, x, y, ..., eol | ||||
|  *   } | ||||
|  * | ||||
|  * The PolyReader object can be used to iterate over the points. | ||||
|  * | ||||
|  *   PolyReader r(data, N_ELEMENTS(data)); | ||||
|  * | ||||
|  *   for(r.start();r.has_more(); r.next()) { | ||||
|  *     uint16_t x = r.x; | ||||
|  *     uint16_t y = r.y; | ||||
|  * | ||||
|  *     // Do something with the point | ||||
|  *         ... | ||||
|  * | ||||
|  *     // Do something else if this point | ||||
|  *     // closes a loop. | ||||
|  *     if (r.end_of_loop()) { | ||||
|  *       ... | ||||
|  *     } | ||||
|  *   } | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| class PolyReader { | ||||
|   private: | ||||
|     typedef uint16_t type_t; | ||||
|  | ||||
|     static constexpr type_t eol = 0xFFFF; | ||||
|  | ||||
|     const type_t *p, *top, *end; | ||||
|     type_t start_x, start_y; | ||||
|  | ||||
|     void close_loop() { | ||||
|       x       = start_x; | ||||
|       y       = start_y; | ||||
|       start_x = eol; | ||||
|       start_y = eol; | ||||
|     } | ||||
|  | ||||
|   public: | ||||
|     type_t x, y; | ||||
|  | ||||
|     // Begin reading a polygon data structure | ||||
|     PolyReader(const uint16_t data[], const size_t n_elements) : top(data), end(data + n_elements) { | ||||
|       start(); | ||||
|     } | ||||
|  | ||||
|     void start() { | ||||
|       p       = top; | ||||
|       start_x = eol; | ||||
|       next(); | ||||
|     } | ||||
|  | ||||
|     // Reads the next point in the polygon data structure | ||||
|     void next() { | ||||
|       if (!p) return; | ||||
|  | ||||
|       if (p == end) { | ||||
|         if (start_x != eol) | ||||
|           close_loop(); | ||||
|         else | ||||
|           p = NULL; | ||||
|       } else { | ||||
|         x = pgm_read_word_far(p++); | ||||
|         if (x == eol) | ||||
|           close_loop(); | ||||
|         else { | ||||
|           y = pgm_read_word_far(p++); | ||||
|           if (start_x == eol) { | ||||
|             start_x = x; | ||||
|             start_y = y; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     bool has_more()       {return p != NULL;} | ||||
|     bool end_of_loop()    {return start_x == eol;} | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * The TransformedPolyReader class works like the PolyReader, | ||||
|  * but the (x,y) input is assumed to be normalized onto a | ||||
|  * unit square and then mapped to the full 16-bits, i.e. | ||||
|  * (0.0,1.0) => (0x0000,0xFFFE). This class will scale the | ||||
|  * data to fit the entire display, a bounding box, or apply | ||||
|  * some arbitrary affine transform. | ||||
|  * | ||||
|  * This class is suitable for reading data from "svg2cpp.py" | ||||
|  */ | ||||
| class TransformedPolyReader : public PolyReader { | ||||
|   private: | ||||
|     /** | ||||
|      * Fixed point type for fast transformations, supports | ||||
|      * values from 0 to 1024, with 1/32 precision. | ||||
|      */ | ||||
|     static constexpr uint8_t fract_bits = 5; | ||||
|     typedef int16_t fix_t; | ||||
|     fix_t makefix(float f) {return f * (1 << fract_bits);} | ||||
|  | ||||
|     // First two rows of 3x3 transformation matrix | ||||
|     fix_t a, b, c; | ||||
|     fix_t d, e, f; | ||||
|  | ||||
|     void transform() { | ||||
|       /** | ||||
|        * Values from PolyReader vary from 0 to FFFE. | ||||
|        * As an approximation to dividing by FFFE, | ||||
|        * we perform a bit shift right by 16. | ||||
|        */ | ||||
|       const int32_t px = PolyReader::x; | ||||
|       const int32_t py = PolyReader::y; | ||||
|       const int32_t round = 1 << (fract_bits-1); | ||||
|       x = (((((a * px) + (b * py)) >> 16) + c) + round) >> fract_bits; | ||||
|       y = (((((d * px) + (e * py)) >> 16) + f) + round) >> fract_bits; | ||||
|     } | ||||
|  | ||||
|     void set_transform( | ||||
|       fix_t A, fix_t B, fix_t C, | ||||
|       fix_t D, fix_t E, fix_t F | ||||
|     ) { | ||||
|       a = A; b = B; c = C; | ||||
|       d = D; e = E; f = F; | ||||
|     } | ||||
|  | ||||
|   public: | ||||
|     typedef int16_t type_t; | ||||
|  | ||||
|     type_t x, y; | ||||
|  | ||||
|     TransformedPolyReader(const uint16_t data[], const size_t n) : PolyReader(data, n) { | ||||
|       scale_to_fit(); | ||||
|       transform(); | ||||
|     } | ||||
|  | ||||
|     // Set an arbitrary affine transform | ||||
|     void set_transform( | ||||
|       float A, float B, float C, | ||||
|       float D, float E, float F | ||||
|     ) { | ||||
|       set_transform( | ||||
|         makefix(A), makefix(B), makefix(C), | ||||
|         makefix(D), makefix(E), makefix(F) | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     // Scale the data to fit a specified bounding box | ||||
|     void scale_to_fit(type_t x_min, type_t y_min, type_t x_max, type_t y_max) { | ||||
|       fix_t sx = makefix(x_max - x_min); | ||||
|       fix_t sy = makefix(y_max - y_min); | ||||
|       fix_t tx = makefix(x_min); | ||||
|       fix_t ty = makefix(y_min); | ||||
|       set_transform( | ||||
|         sx,  0, tx, | ||||
|         0,  sy, ty | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     // Scale to fit the entire display (default) | ||||
|     void scale_to_fit() { | ||||
|       scale_to_fit(0, 0, FTDI::display_width, FTDI::display_height); | ||||
|     } | ||||
|  | ||||
|     void next() { | ||||
|       PolyReader::next(); | ||||
|       transform(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * The DeduplicatedPolyReader wraps around another PolyReader | ||||
|  * class to remove repeated points from the data. This could | ||||
|  * happen when scaling down using TransformedPolyReader, for | ||||
|  * example. | ||||
|  */ | ||||
| template<class POLY_READER> | ||||
| class DeduplicatedPolyReader : public POLY_READER { | ||||
|   private: | ||||
|     typename POLY_READER::type_t last_x, last_y; | ||||
|  | ||||
|     static constexpr typename POLY_READER::type_t eol = 0xFFFF; | ||||
|  | ||||
|   public: | ||||
|     DeduplicatedPolyReader(const uint16_t data[], const size_t n) : POLY_READER(data, n) { | ||||
|       last_x = POLY_READER::x; | ||||
|       last_y = POLY_READER::y; | ||||
|     } | ||||
|  | ||||
|     void next() { | ||||
|       do { | ||||
|         if (!POLY_READER::has_more()) return; | ||||
|         POLY_READER::next(); | ||||
|       } while (POLY_READER::x == last_x && POLY_READER::y == last_y && !POLY_READER::end_of_loop()); | ||||
|       if (POLY_READER::end_of_loop()) { | ||||
|         last_x = last_y = eol; | ||||
|       } else { | ||||
|         last_x = POLY_READER::x; | ||||
|         last_y = POLY_READER::y; | ||||
|       } | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * The helper class allows you to build an interface based on arbitrary | ||||
|  * shapes. | ||||
|  */ | ||||
| template<class POLY_READER=DeduplicatedPolyReader<TransformedPolyReader>> | ||||
| class GenericPolyUI { | ||||
|   private: | ||||
|     CommandProcessor &cmd; | ||||
|  | ||||
|     // Attributes used to paint buttons | ||||
|  | ||||
|     uint32_t btn_fill_color   = 0x000000; | ||||
|     uint32_t btn_shadow_color = 0xF3E0E0; | ||||
|     uint8_t  btn_shadow_depth = 5; | ||||
|     uint32_t btn_stroke_color = 0x000000; | ||||
|     uint8_t  btn_stroke_width = 28; | ||||
|  | ||||
|     draw_mode_t mode; | ||||
|  | ||||
|   public: | ||||
|     typedef POLY_READER poly_reader_t; | ||||
|  | ||||
|     GenericPolyUI(CommandProcessor &c, draw_mode_t what = BOTH) : cmd(c), mode(what) {} | ||||
|  | ||||
|     // Fills a polygon with the current COLOR_RGB | ||||
|     void fill(poly_reader_t r, bool clip = true) { | ||||
|       using namespace FTDI; | ||||
|       int16_t x, y, w, h; | ||||
|  | ||||
|       if (clip) { | ||||
|         // Clipping reduces the number of pixels that are | ||||
|         // filled, allowing more complex shapes to be drawn | ||||
|         // in the alloted time. | ||||
|         bounds(r, x, y, w, h); | ||||
|         cmd.cmd(SAVE_CONTEXT()); | ||||
|         cmd.cmd(SCISSOR_XY(x, y)); | ||||
|         cmd.cmd(SCISSOR_SIZE(w, h)); | ||||
|       } | ||||
|  | ||||
|       Polygon p(cmd); | ||||
|       p.begin_fill(); | ||||
|       p.begin_loop(); | ||||
|       for(r.start();r.has_more();r.next()) { | ||||
|         p(r.x * 16, r.y * 16); | ||||
|         if (r.end_of_loop()) { | ||||
|           p.end_loop(); | ||||
|           p.begin_loop(); | ||||
|         } | ||||
|       } | ||||
|       p.end_loop(); | ||||
|       p.end_fill(); | ||||
|       if (clip) | ||||
|         cmd.cmd(RESTORE_CONTEXT()); | ||||
|     } | ||||
|  | ||||
|     void shadow(poly_reader_t r, uint8_t offset) { | ||||
|       #if FTDI_API_LEVEL >= 810 | ||||
|         using namespace FTDI; | ||||
|         cmd.cmd(VERTEX_TRANSLATE_X(offset * 16)); | ||||
|         cmd.cmd(VERTEX_TRANSLATE_Y(offset * 16)); | ||||
|         fill(r, false); | ||||
|         cmd.cmd(VERTEX_TRANSLATE_X(0)); | ||||
|         cmd.cmd(VERTEX_TRANSLATE_Y(0)); | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
|     // Strokes a polygon with the current COLOR_RGB | ||||
|     void stroke(poly_reader_t r) { | ||||
|       using namespace FTDI; | ||||
|       Polygon p(cmd); | ||||
|       p.begin_stroke(); | ||||
|       p.begin_loop(); | ||||
|       for(r.start();r.has_more(); r.next()) { | ||||
|         p(r.x * 16, r.y * 16); | ||||
|         if (r.end_of_loop()) { | ||||
|           p.end_loop(); | ||||
|           p.begin_loop(); | ||||
|         } | ||||
|       } | ||||
|       p.end_loop(); | ||||
|       p.end_stroke(); | ||||
|     } | ||||
|  | ||||
|     // Compute the bounds of a polygon | ||||
|     void bounds(poly_reader_t r, int16_t &x, int16_t &y, int16_t &w, int16_t &h) { | ||||
|       int16_t x_min = INT16_MAX; | ||||
|       int16_t y_min = INT16_MAX; | ||||
|       int16_t x_max = INT16_MIN; | ||||
|       int16_t y_max = INT16_MIN; | ||||
|       for(r.start(); r.has_more(); r.next()) { | ||||
|         x_min = min(x_min, r.x); | ||||
|         x_max = max(x_max, r.x); | ||||
|         y_min = min(y_min, r.y); | ||||
|         y_max = max(y_max, r.y); | ||||
|       } | ||||
|       x = x_min; | ||||
|       y = y_min; | ||||
|       w = x_max - x_min; | ||||
|       h = y_max - y_min; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Draw shaped buttons. Buttons are drawn out of a polygon which is | ||||
|      * filled and stroked on top of a drop shadow. The button will | ||||
|      * become "pushed" when touched. | ||||
|      */ | ||||
|  | ||||
|     void button_fill(const uint32_t color) { | ||||
|       btn_fill_color = color; | ||||
|     } | ||||
|  | ||||
|     void button_stroke(const uint32_t color, const uint8_t width) { | ||||
|       btn_stroke_color = color; | ||||
|       btn_stroke_width = width; | ||||
|     } | ||||
|  | ||||
|     void button_shadow(const uint32_t color, const uint8_t depth) { | ||||
|       btn_shadow_color = color; | ||||
|       btn_shadow_depth = depth; | ||||
|     } | ||||
|  | ||||
|     void button(const uint8_t tag, poly_reader_t r) { | ||||
|       using namespace FTDI; | ||||
|       // Draw the shadow | ||||
|       #if FTDI_API_LEVEL >= 810 | ||||
|       if (mode & BACKGROUND) { | ||||
|         cmd.cmd(SAVE_CONTEXT()); | ||||
|         cmd.cmd(TAG(tag)); | ||||
|         cmd.cmd(VERTEX_TRANSLATE_X(btn_shadow_depth * 16)); | ||||
|         cmd.cmd(VERTEX_TRANSLATE_Y(btn_shadow_depth * 16)); | ||||
|         cmd.cmd(COLOR_RGB(btn_shadow_color)); | ||||
|         fill(r, false); | ||||
|         cmd.cmd(RESTORE_CONTEXT()); | ||||
|       } | ||||
|       #endif | ||||
|  | ||||
|       if (mode & FOREGROUND) { | ||||
|         cmd.cmd(SAVE_CONTEXT()); | ||||
|         #if FTDI_API_LEVEL >= 810 | ||||
|           if (EventLoop::get_pressed_tag() == tag) { | ||||
|             // "Push" the button | ||||
|             cmd.cmd(VERTEX_TRANSLATE_X(btn_shadow_depth * 16)); | ||||
|             cmd.cmd(VERTEX_TRANSLATE_Y(btn_shadow_depth * 16)); | ||||
|           } | ||||
|         #endif | ||||
|         // Draw the fill and stroke | ||||
|         cmd.cmd(TAG(tag)); | ||||
|         cmd.cmd(COLOR_RGB(btn_fill_color)); | ||||
|         fill(r, false); | ||||
|         cmd.cmd(COLOR_RGB(btn_stroke_color)); | ||||
|         cmd.cmd(LINE_WIDTH(btn_stroke_width)); | ||||
|         stroke(r); | ||||
|         cmd.cmd(RESTORE_CONTEXT()); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     void color(const uint32_t color) { | ||||
|       cmd.cmd(FTDI::COLOR_RGB(color)); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| typedef GenericPolyUI<> PolyUI; | ||||
							
								
								
									
										278
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/svg2cpp.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										278
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/svg2cpp.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| #!/usr/bin/python | ||||
|  | ||||
| # 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/>. | ||||
|  | ||||
| from __future__ import print_function | ||||
| import argparse, re, sys | ||||
|  | ||||
| usage = ''' | ||||
| This program extracts line segments from a SVG file and writes | ||||
| them as coordinates in a C array. The x and y values will be | ||||
| scaled from 0x0000 to 0xFFFE. 0xFFFF is used as path separator. | ||||
|  | ||||
| This program can only interpret straight segments, not curves. | ||||
| It also cannot handle SVG transform attributes. To convert an | ||||
| SVG file into the proper format, use the following procedure: | ||||
|  | ||||
|   - Load SVG file into Inkscape | ||||
|   - Convert all Objects to Paths (Path -> Object to Path) | ||||
|   - Convert all Strokes to Paths (Path -> Stroke to Path) | ||||
|   - Combine all paths into one (Path -> Combine) [1] | ||||
|   - Convert all curves into short line segments | ||||
|             (Extensions -> Modify Paths -> Flatten Beziers...) | ||||
|   - Save as new SVG | ||||
|   - Convert into a header file using this utility | ||||
|   - To give paths individual names, break apart paths and | ||||
|     use the XML Editor to set the "id" attributes. | ||||
|  | ||||
| [1] Combining paths is necessary to remove transforms. You | ||||
| could also use inkscape-applytransforms Inkscape extension. | ||||
|  | ||||
| ''' | ||||
|  | ||||
| header = ''' | ||||
| /**************************************************************************** | ||||
|  *   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 file was auto-generated using "svg2cpp.pl" | ||||
|  * | ||||
|  * The encoding consists of x,y pairs with the min and max scaled to | ||||
|  * 0x0000 and 0xFFFE. A single 0xFFFF in the data stream indicates the | ||||
|  * start of a new closed path. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
| ''' | ||||
|  | ||||
| class ComputeBoundingBox: | ||||
|   def reset(self): | ||||
|     self.x_min    = float(" inf") | ||||
|     self.y_min    = float(" inf") | ||||
|     self.x_max    = float("-inf") | ||||
|     self.y_max    = float("-inf") | ||||
|     self.n_points = 0 | ||||
|     self.n_paths  = 0 | ||||
|  | ||||
|   def command(self, type, x, y): | ||||
|     self.x_min = min(self.x_min, x) | ||||
|     self.x_max = max(self.x_max, x) | ||||
|     self.y_min = min(self.y_min, y) | ||||
|     self.y_max = max(self.y_max, y) | ||||
|  | ||||
|     if type == "M": | ||||
|       self.n_paths += 1 | ||||
|     self.n_points += 1 | ||||
|  | ||||
|   def scale(self, x, y): | ||||
|     x -= self.x_min | ||||
|     y -= self.y_min | ||||
|     x /= self.x_max - self.x_min | ||||
|     y /= self.y_max - self.y_min | ||||
|     #y = 1 - y # Flip upside down | ||||
|     return (x, y) | ||||
|  | ||||
|   def path_finished(self, id): | ||||
|     pass | ||||
|  | ||||
|   def write(self): | ||||
|     print("constexpr float x_min = %f;\n" % self.x_min) | ||||
|     print("constexpr float x_max = %f;\n" % self.x_max) | ||||
|     print("constexpr float y_min = %f;\n" % self.y_min) | ||||
|     print("constexpr float y_max = %f;\n" % self.y_max) | ||||
|  | ||||
|   def from_svg_view_box(self, svg): | ||||
|     s = re.search('<svg[^>]+>', svg); | ||||
|     if s: | ||||
|       m = re.search('viewBox="([0-9-.]+) ([0-9-.]+) ([0-9-.]+) ([0-9-.]+)"', svg) | ||||
|       if m: | ||||
|         self.x_min    = float(m.group(1)) | ||||
|         self.y_min    = float(m.group(2)) | ||||
|         self.x_max    = float(m.group(3)) | ||||
|         self.y_max    = float(m.group(4)) | ||||
|         return True | ||||
|     return False | ||||
|  | ||||
| class WriteDataStructure: | ||||
|   def __init__(self, bounding_box): | ||||
|     self.bounds = bounding_box | ||||
|  | ||||
|   def reset(self, ): | ||||
|     self.hex_words = [] | ||||
|  | ||||
|   def push(self, value): | ||||
|     self.hex_words.append("0x%04X" % value) | ||||
|  | ||||
|   def command(self, type, x, y): | ||||
|     if type == "M": | ||||
|       self.push(0xFFFF) | ||||
|     x, y = self.bounds.scale(x,y) | ||||
|     self.push(x * 0xFFFE) | ||||
|     self.push(y * 0xFFFE) | ||||
|  | ||||
|   def path_finished(self, id): | ||||
|     if self.hex_words and self.hex_words[0] == "0xFFFF": | ||||
|       self.hex_words.pop(0) | ||||
|     print("const PROGMEM uint16_t", id + "[] = {" + ", ".join (self.hex_words) + "};\n") | ||||
|     self.hex_words = [] | ||||
|  | ||||
| class Parser: | ||||
|   def __init__(self, op): | ||||
|     self.op = op | ||||
|     self.reset() | ||||
|  | ||||
|   def reset(self): | ||||
|     self.last_x = 0 | ||||
|     self.last_y = 0 | ||||
|     self.initial_x = 0 | ||||
|     self.initial_y = 0 | ||||
|  | ||||
|   def process_svg_path_L_or_M(self, cmd, x, y): | ||||
|     self.op.command(cmd, x, y) | ||||
|     self.last_x = x | ||||
|     self.last_y = y | ||||
|     if cmd == "M": | ||||
|       self.initial_x = x | ||||
|       self.initial_y = y | ||||
|  | ||||
|   def process_svg_path_data_cmd(self, id, cmd, a, b): | ||||
|     """Converts the various types of moves into L or M commands | ||||
|     and dispatches to process_svg_path_L_or_M for futher processing.""" | ||||
|     if cmd == "Z" or cmd == "z": | ||||
|       self.process_svg_path_L_or_M("L", self.initial_x, self.initial_y) | ||||
|     elif cmd == "H": | ||||
|       self.process_svg_path_L_or_M("L", a, self.last_y) | ||||
|     elif cmd == "V": | ||||
|       self.process_svg_path_L_or_M("L", self.last_x, a) | ||||
|     elif cmd == "h": | ||||
|       self.process_svg_path_L_or_M("L", self.last_x + a, self.last_y) | ||||
|     elif cmd == "v": | ||||
|       self.process_svg_path_L_or_M("L", self.last_x, self.last_y + a) | ||||
|     elif cmd == "L": | ||||
|       self.process_svg_path_L_or_M("L", a, b) | ||||
|     elif cmd == "l": | ||||
|       self.process_svg_path_L_or_M("L", self.last_x + a, self.last_y + b) | ||||
|     elif cmd == "M": | ||||
|       self.process_svg_path_L_or_M("M", a, b) | ||||
|     elif cmd == "m": | ||||
|       self.process_svg_path_L_or_M("M", self.last_x + a, self.last_y + b) | ||||
|     else: | ||||
|       print("Unsupported path data command:", cmd, "in path", id, "\n", file=sys.stderr) | ||||
|       quit() | ||||
|  | ||||
|   def eat_token(self, regex): | ||||
|     """Looks for a token at the start of self.d. | ||||
|        If found, the token is removed.""" | ||||
|     self.m = re.match(regex,self.d) | ||||
|     if self.m: | ||||
|       self.d = self.d[self.m.end():] | ||||
|     return self.m | ||||
|  | ||||
|   def process_svg_path_data(self, id, d): | ||||
|     """Breaks up the "d" attribute into individual commands | ||||
|        and calls "process_svg_path_data_cmd" for each""" | ||||
|  | ||||
|     self.d = d | ||||
|     while (self.d): | ||||
|       if self.eat_token('\s+'): | ||||
|         pass # Just eat the spaces | ||||
|  | ||||
|       elif self.eat_token('([LMHVZlmhvz])'): | ||||
|         cmd = self.m.group(1) | ||||
|         # The following commands take no arguments | ||||
|         if cmd == "Z" or cmd == "z": | ||||
|           self.process_svg_path_data_cmd(id, cmd, 0, 0) | ||||
|  | ||||
|       elif self.eat_token('([CScsQqTtAa])'): | ||||
|         print("Unsupported path data command:", self.m.group(1), "in path", id, "\n", file=sys.stderr) | ||||
|         quit() | ||||
|  | ||||
|       elif self.eat_token('([ ,]*[-0-9e.]+)+'): | ||||
|         # Process list of coordinates following command | ||||
|         coords = re.split('[ ,]+', self.m.group(0)) | ||||
|         # The following commands take two arguments | ||||
|         if cmd == "L" or cmd == "l": | ||||
|           while coords: | ||||
|             self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), float(coords.pop(0))) | ||||
|         elif cmd == "M": | ||||
|           while coords: | ||||
|             self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), float(coords.pop(0))) | ||||
|             # If a MOVETO has multiple points, the subsequent ones are assumed to be LINETO | ||||
|             cmd = "L" | ||||
|         elif cmd == "m": | ||||
|           while coords: | ||||
|             self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), float(coords.pop(0))) | ||||
|             # If a MOVETO has multiple points, the subsequent ones are assumed to be LINETO | ||||
|             cmd = "l" | ||||
|         # Assume all other commands are single argument | ||||
|         else: | ||||
|           while coords: | ||||
|             self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), 0) | ||||
|       else: | ||||
|         print("Syntax error:", d, "in path", id, "\n", file=sys.stderr) | ||||
|         quit() | ||||
|  | ||||
|   def process_svg_paths(self, svg): | ||||
|     self.op.reset() | ||||
|     for path in re.findall('<path[^>]+>', svg): | ||||
|       id = "<none>" | ||||
|       m = re.search(' id="(.*)"', path) | ||||
|       if m: | ||||
|         id = m.group(1) | ||||
|  | ||||
|       m = re.search(' transform="(.*)"', path) | ||||
|       if m: | ||||
|         print("Found transform in path", id, "! Cannot process file!", file=sys.stderr) | ||||
|         quit() | ||||
|  | ||||
|       m = re.search(' d="(.*)"', path) | ||||
|       if m: | ||||
|         self.process_svg_path_data(id, m.group(1)) | ||||
|         self.op.path_finished(id) | ||||
|         self.reset() | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|   parser = argparse.ArgumentParser() | ||||
|   parser.add_argument("filename") | ||||
|   args = parser.parse_args() | ||||
|  | ||||
|   f = open(args.filename, "r") | ||||
|   data = f.read() | ||||
|  | ||||
|   print(header) | ||||
|  | ||||
|   b = ComputeBoundingBox() | ||||
|   if not b.from_svg_view_box(data): | ||||
|     # Can't find the view box, so use the bounding box of the elements themselves. | ||||
|     p = Parser(b) | ||||
|     p.process_svg_paths(data) | ||||
|   b.write() | ||||
|  | ||||
|   w = WriteDataStructure(b) | ||||
|   p = Parser(w) | ||||
|   p.process_svg_paths(data) | ||||
| @@ -0,0 +1,27 @@ | ||||
| /****************** | ||||
|  * ftdi_eve_lib.h * | ||||
|  ******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2019 - Aleph Objects, Inc.                  * | ||||
|  *   Written By Marcio Teixeira 2019 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "compat.h" | ||||
| #include "basic/ftdi_basic.h" | ||||
| #include "extended/ftdi_extended.h" | ||||
							
								
								
									
										128
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/marlin_events.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/marlin_events.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| /********************* | ||||
|  * marlin_events.cpp * | ||||
|  *********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "compat.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens/screens.h" | ||||
|  | ||||
| namespace ExtUI { | ||||
|   using namespace Theme; | ||||
|   using namespace FTDI; | ||||
|  | ||||
|   void onStartup() { | ||||
|     EventLoop::setup(); | ||||
|   } | ||||
|  | ||||
|   void onIdle() { | ||||
|     EventLoop::loop(); | ||||
|   } | ||||
|  | ||||
|   void onPrinterKilled(PGM_P lcd_msg) { | ||||
|     KillScreen::show(progmem_str(lcd_msg)); | ||||
|   } | ||||
|  | ||||
|   void onMediaInserted() { | ||||
|     if (AT_SCREEN(StatusScreen)) | ||||
|       StatusScreen::setStatusMessage(F(MSG_MEDIA_INSERTED)); | ||||
|     sound.play(media_inserted, PLAY_ASYNCHRONOUS); | ||||
|   } | ||||
|  | ||||
|   void onMediaRemoved() { | ||||
|     if (AT_SCREEN(StatusScreen)) | ||||
|       StatusScreen::setStatusMessage(F(MSG_MEDIA_REMOVED)); | ||||
|     sound.play(media_removed, PLAY_ASYNCHRONOUS); | ||||
|     if (AT_SCREEN(FilesScreen)) { | ||||
|       GOTO_SCREEN(StatusScreen) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void onMediaError() { | ||||
|     sound.play(sad_trombone, PLAY_ASYNCHRONOUS); | ||||
|     AlertDialogBox::showError(F("Unable to read media.")); | ||||
|   } | ||||
|  | ||||
|   void onStatusChanged(const char* lcd_msg) { | ||||
|     StatusScreen::setStatusMessage(lcd_msg); | ||||
|   } | ||||
|  | ||||
|   void onStatusChanged(progmem_str lcd_msg) { | ||||
|     StatusScreen::setStatusMessage(lcd_msg); | ||||
|   } | ||||
|  | ||||
|   void onPrintTimerStarted() { | ||||
|     InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_STARTED); | ||||
|   } | ||||
|  | ||||
|   void onPrintTimerStopped() { | ||||
|     InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FINISHED); | ||||
|   } | ||||
|  | ||||
|   void onPrintTimerPaused() { | ||||
|   } | ||||
|  | ||||
|   void onFilamentRunout(const extruder_t extruder) { | ||||
|     char lcd_msg[30]; | ||||
|     sprintf_P(lcd_msg, PSTR("Extruder %d Filament Error"), extruder + 1); | ||||
|     StatusScreen::setStatusMessage(lcd_msg); | ||||
|     InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED); | ||||
|   } | ||||
|  | ||||
|   void onFactoryReset() { | ||||
|     InterfaceSettingsScreen::defaultSettings(); | ||||
|   } | ||||
|  | ||||
|   void onStoreSettings(char *buff) { | ||||
|     InterfaceSettingsScreen::saveSettings(buff); | ||||
|   } | ||||
|  | ||||
|   void onLoadSettings(const char *buff) { | ||||
|     InterfaceSettingsScreen::loadSettings(buff); | ||||
|   } | ||||
|  | ||||
|   void onConfigurationStoreWritten(bool success) { | ||||
|     #ifdef LULZBOT_EEPROM_BACKUP_SIZE | ||||
|       if (success && InterfaceSettingsScreen::backupEEPROM()) { | ||||
|         SERIAL_ECHOLNPGM("Made backup of EEPROM to SPI Flash"); | ||||
|       } | ||||
|     #else | ||||
|       UNUSED(success); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   void onConfigurationStoreRead(bool) { | ||||
|   } | ||||
|  | ||||
|   void onPlayTone(const uint16_t frequency, const uint16_t duration) { | ||||
|     sound.play_tone(frequency, duration); | ||||
|   } | ||||
|  | ||||
|   void onUserConfirmRequired(const char * const msg) { | ||||
|     if (msg) | ||||
|       ConfirmUserRequestAlertBox::show(msg); | ||||
|     else | ||||
|       ConfirmUserRequestAlertBox::hide(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
							
								
								
									
										142
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/pin_mappings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/pin_mappings.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| /****************** | ||||
|  * pin_mappings.h * | ||||
|  ******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /* This file defines mappings from the ULTRA_LCD pins functions to new | ||||
|  * functions for the FTDI display. These mappings allows any board that | ||||
|  * support ULTRA_LCD via EXP1 and EXP2 connectors to use FTDI modules | ||||
|  * without adding new pin definitions to the board. | ||||
|  */ | ||||
|  | ||||
| #ifdef CR10_TFT_PINMAP | ||||
|   #ifndef __MARLIN_FIRMWARE__ | ||||
|     #error This pin mapping requires Marlin. | ||||
|   #endif | ||||
|  | ||||
|   #define CLCD_USE_SOFT_SPI | ||||
|   #define CLCD_SOFT_SPI_SCLK  LCD_PINS_D4      // PORTA1               Pin 6 | ||||
|   #define CLCD_SOFT_SPI_MOSI  LCD_PINS_ENABLE  // PORTC1               Pin 8 | ||||
|   #define CLCD_SPI_CS         LCD_PINS_RS      // PORTA3               Pin 7 | ||||
|   #define CLCD_SOFT_SPI_MISO  16               // PORTC0   BTN_ENC     Pin 2 | ||||
|   #define CLCD_MOD_RESET      11               // PORTD3   BTN_EN1     Pin 3 | ||||
|   #define CLCD_AUX_0          10               // PORTD2   BTN_EN2     Pin 5 | ||||
|   #define CLCD_AUX_1          BEEPER_PIN       // PORTA4               Pin 1 | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * The AlephObjects pinout for re-purposing the UltraLCD | ||||
|  * connector EXP1 for software SPI (rev B, obsolete) | ||||
|  */ | ||||
|  | ||||
| #ifdef AO_EXP1_DEPRECATED_PINMAP | ||||
|   #ifndef __MARLIN_FIRMWARE__ | ||||
|     #error This pin mapping requires Marlin. | ||||
|   #endif | ||||
|  | ||||
|   #define CLCD_MOD_RESET                 LCD_PINS_D4 | ||||
|   #define CLCD_SPI_CS                    LCD_PINS_D5 | ||||
|  | ||||
|   #define CLCD_AUX_0                     LCD_PINS_ENABLE | ||||
|   #define CLCD_AUX_1                     BTN_ENC | ||||
|   #define CLCD_AUX_2                     BEEPER_PIN | ||||
|  | ||||
|   #define CLCD_USE_SOFT_SPI | ||||
|   #define CLCD_SOFT_SPI_SCLK             LCD_PINS_D7 | ||||
|   #define CLCD_SOFT_SPI_MOSI             LCD_PINS_D6 | ||||
|   #define CLCD_SOFT_SPI_MISO             LCD_PINS_RS | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * AO_EXP1_PINMAP | ||||
|  * | ||||
|  * The AlephObjects mapping for re-purposing the UltraLCD | ||||
|  * connector EXP1 for software SPI for display (rev C): | ||||
|  * | ||||
|  *     EXP2:      FTDI:   SD -or- USB [1]:     ULTRA_LCD: | ||||
|  *      1         MISO    MISO    MISO    -->  BEEPER | ||||
|  *      2         SCLK    SCLK    SCLK    -->  BTN_ENC | ||||
|  *      3         PD_N      -      -      -->  LCDE | ||||
|  *      4          -      CS_N    CS_N    -->  LCDRS | ||||
|  *      5         CS_N      -      -      -->  LCD4 | ||||
|  *      6         MOSI    MOSI    MOSI    -->  LCD5 | ||||
|  *      7          -      SD_DET  INT     -->  LCD6 | ||||
|  *      8         RESET     -     RESET   -->  LCD4 | ||||
|  *      9         GND     GND     GND     -->  GND | ||||
|  *     10         5V      5V      5V      -->  5V | ||||
|  * | ||||
|  *     [1] At the moment, Marlin does not support SD or USB | ||||
|  *         functionality over software SPI. | ||||
|  */ | ||||
|  | ||||
| #ifdef AO_EXP1_PINMAP | ||||
|   #ifndef __MARLIN_FIRMWARE__ | ||||
|     #error This pin mapping requires Marlin. | ||||
|   #endif | ||||
|  | ||||
|   #define CLCD_MOD_RESET                 LCD_PINS_ENABLE | ||||
|   #define CLCD_SPI_CS                    LCD_PINS_D4 | ||||
|  | ||||
|   #define CLCD_USE_SOFT_SPI | ||||
|   #define CLCD_SOFT_SPI_SCLK             BTN_ENC | ||||
|   #define CLCD_SOFT_SPI_MOSI             LCD_PINS_D5 | ||||
|   #define CLCD_SOFT_SPI_MISO             BEEPER_PIN | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * AO_EXP2_PINMAP | ||||
|  * | ||||
|  * The AlephObjects mapping for re-purposing the UltraLCD | ||||
|  * connector EXP2 for hardware SPI for display and SD card | ||||
|  * or USB (rev C): | ||||
|  * | ||||
|  *     EXP2:      FTDI:   SD -or- USB:         ULTRA_LCD: | ||||
|  *      1         MISO    MISO    MISO    -->  MISO | ||||
|  *      2         SCLK    SCLK    SCLK    -->  SCLK | ||||
|  *      3         PD_N      -      -      -->  BTN_EN2 | ||||
|  *      4          -      CS_N    CS_N    -->  SD_CSEL | ||||
|  *      5         CS_N      -      -      -->  BTN_EN1 | ||||
|  *      6         MOSI    MOSI    MOSI    -->  MOSI | ||||
|  *      7          -      SD_DET  INT     -->  SD_DET | ||||
|  *      8         RESET     -     RESET   -->  RESET | ||||
|  *      9         GND     GND     GND     -->  GND | ||||
|  *     10         5V      5V      5V      -->  KILL [3] | ||||
|  * | ||||
|  * [1] This configuration is not compatible with the | ||||
|  *     EinsyRetro 1.1a because there is a level shifter | ||||
|  *     on MISO enabled by SD/USB chip select. | ||||
|  * | ||||
|  * [2] This configuration allows daisy-chaining of the | ||||
|  *     display and SD/USB on EXP2. | ||||
|  * | ||||
|  * [3] Archim Rambo provides 5V on this pin. On any other | ||||
|  *     board, divert this wire from the ribbon cable and | ||||
|  *     connect it to 5V at an endstop. | ||||
|  */ | ||||
|  | ||||
| #ifdef AO_EXP2_PINMAP | ||||
|   #ifndef __MARLIN_FIRMWARE__ | ||||
|     #error This pin mapping requires Marlin. | ||||
|   #endif | ||||
|  | ||||
|   #define CLCD_SPI_CS                    BTN_EN1 | ||||
|   #define CLCD_MOD_RESET                 BTN_EN2 | ||||
| #endif | ||||
| @@ -0,0 +1,80 @@ | ||||
| /******************** | ||||
|  * about_screen.cpp * | ||||
|  ********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| #define GRID_COLS 4 | ||||
| #define GRID_ROWS 9 | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
| using namespace ExtUI; | ||||
|  | ||||
| void AboutScreen::onEntry() { | ||||
|   BaseScreen::onEntry(); | ||||
|   sound.play(chimes, PLAY_ASYNCHRONOUS); | ||||
| } | ||||
|  | ||||
| void AboutScreen::onRedraw(draw_mode_t) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|      .cmd(CLEAR(true,true,true)) | ||||
|      .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|      .tag(0); | ||||
|  | ||||
|   draw_text_box(cmd, BTN_POS(1,2), BTN_SIZE(4,1), F( | ||||
|       #ifdef LULZBOT_LCD_MACHINE_NAME | ||||
|       LULZBOT_LCD_MACHINE_NAME | ||||
|       #else | ||||
|       "Color Touch Panel" | ||||
|       #endif | ||||
|     ), OPT_CENTER, font_xlarge); | ||||
|  | ||||
|   cmd.tag(2); | ||||
|   draw_text_box(cmd, BTN_POS(1,3), BTN_SIZE(4,3), F( | ||||
|       #ifdef LULZBOT_LCD_TOOLHEAD_NAME | ||||
|         "Firmware for toolhead:\n" LULZBOT_LCD_TOOLHEAD_NAME "\n\n" | ||||
|       #endif | ||||
|       "(C) 2019 Aleph Objects, Inc.\n\nwww.lulzbot.com" | ||||
|   ), OPT_CENTER, font_medium); | ||||
|  | ||||
|   cmd.tag(0); | ||||
|   draw_text_box(cmd, BTN_POS(1,6), BTN_SIZE(4,2), progmem_str(getFirmwareName_str()), OPT_CENTER, font_medium); | ||||
|  | ||||
|   cmd.font(font_medium).colors(action_btn).tag(1).button(BTN_POS(2,8), BTN_SIZE(2,1), F("Okay")); | ||||
| } | ||||
|  | ||||
| bool AboutScreen::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS();            return true; | ||||
| #if ENABLED(DEVELOPER_SCREENS) | ||||
|     case 2: GOTO_SCREEN(DeveloperMenu); return true; | ||||
| #endif | ||||
|     default:                            return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,191 @@ | ||||
| /***************************** | ||||
|  * advance_settings_menu.cpp * | ||||
|  *****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && !defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void AdvancedSettingsMenu::onRedraw(draw_mode_t what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.colors(normal_btn) | ||||
|        .font(Theme::font_medium) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       #define GRID_ROWS 9 | ||||
|       #define GRID_COLS 2 | ||||
|       #if HAS_BED_PROBE | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), F("Z Offset ")) | ||||
|       .enabled(1) | ||||
|       .tag(3) .button( BTN_POS(2,1), BTN_SIZE(1,1), F("Steps/mm")) | ||||
|       #if HAS_TRINAMIC | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(13).button( BTN_POS(1,5), BTN_SIZE(1,1), F("Motor mA")) | ||||
|       #if HAS_TRINAMIC | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(14).button( BTN_POS(1,4), BTN_SIZE(1,1), F("Bump Sense")) | ||||
|       #if HOTENDS > 1 | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(4) .button( BTN_POS(1,2), BTN_SIZE(1,1), F("Nozzle Offset")) | ||||
|       #if ENABLED(LIN_ADVANCE) || ENABLED(FILAMENT_RUNOUT_SENSOR) | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(11).button( BTN_POS(1,3), BTN_SIZE(1,1), F("Filament")) | ||||
|       .tag(12).button( BTN_POS(1,6), BTN_SIZE(1,1), F("Endstops")) | ||||
|       .tag(15).button( BTN_POS(2,6), BTN_SIZE(1,1), F("Display")) | ||||
|       .tag(9) .button( BTN_POS(1,7), BTN_SIZE(2,1), F("Interface Settings")) | ||||
|       .tag(10).button( BTN_POS(1,8), BTN_SIZE(2,1), F("Restore Factory Defaults")) | ||||
|       .tag(5) .button( BTN_POS(2,2), BTN_SIZE(1,1), F("Velocity ")) | ||||
|       .tag(6) .button( BTN_POS(2,3), BTN_SIZE(1,1), F("Acceleration")) | ||||
|       #if ENABLED(JUNCTION_DEVIATION) | ||||
|       .tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), F("Junc Dev")) | ||||
|       #else | ||||
|       .tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), F("Jerk")) | ||||
|       #endif | ||||
|       #if ENABLED(BACKLASH_GCODE) | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(8).button( BTN_POS(2,5), BTN_SIZE(1,1), F("Backlash")) | ||||
|       .colors(action_btn) | ||||
|       .tag(1) .button( BTN_POS(1,9), BTN_SIZE(2,1), F("Back")); | ||||
|       #undef GRID_COLS | ||||
|       #undef GRID_ROWS | ||||
|     #else | ||||
|       #define GRID_ROWS 6 | ||||
|       #define GRID_COLS 3 | ||||
|       #if HAS_BED_PROBE | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(2) .button( BTN_POS(1,1),  BTN_SIZE(1,2), F("Z Offset ")) | ||||
|       .enabled(1) | ||||
|       .tag(3) .button( BTN_POS(2,1),  BTN_SIZE(1,1), F("Steps/mm")) | ||||
|       #if HAS_TRINAMIC | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(13).button( BTN_POS(3,1), BTN_SIZE(1,1), F("Motor mA")) | ||||
|       #if HAS_TRINAMIC | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(14).button( BTN_POS(3,2), BTN_SIZE(1,1), F("Bump Sense")) | ||||
|       #if ENABLED(BACKLASH_GCODE) | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(8).button( BTN_POS(3,3),  BTN_SIZE(1,1), F("Backlash")) | ||||
|       #if HOTENDS > 1 | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(4) .button( BTN_POS(1,3),  BTN_SIZE(1,1), F("Nozzle Offsets")) | ||||
|       .tag(12).button( BTN_POS(3,4),  BTN_SIZE(1,1), F("Endstops")) | ||||
|       .tag(5) .button( BTN_POS(2,2),  BTN_SIZE(1,1), F("Velocity ")) | ||||
|       .tag(6) .button( BTN_POS(2,3),  BTN_SIZE(1,1), F("Acceleration")) | ||||
|       #if ENABLED(JUNCTION_DEVIATION) | ||||
|       .tag(7) .button( BTN_POS(2,4),  BTN_SIZE(1,1), F("Junc Dev")) | ||||
|       #else | ||||
|       .tag(7) .button( BTN_POS(2,4),  BTN_SIZE(1,1), F("Jerk")) | ||||
|       #endif | ||||
|       .tag(11).button( BTN_POS(1,4),  BTN_SIZE(1,1), F("Filament")) | ||||
|       .tag(15).button( BTN_POS(3,5),  BTN_SIZE(1,1), F("Display")) | ||||
|       .tag(9) .button( BTN_POS(1,5),  BTN_SIZE(2,1), F("Interface Settings")) | ||||
|       .tag(10).button( BTN_POS(1,6),  BTN_SIZE(2,1), F("Restore Defaults")) | ||||
|       .colors(action_btn) | ||||
|       .tag(1) .button( BTN_POS(3,6),  BTN_SIZE(1,1), F("Back")); | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: SaveSettingsDialogBox::promptToSaveSettings(); break; | ||||
|     #if HAS_BED_PROBE | ||||
|     case 2:  GOTO_SCREEN(ZOffsetScreen);              break; | ||||
|     #endif | ||||
|     case 3:  GOTO_SCREEN(StepsScreen);                break; | ||||
|     #if HOTENDS > 1 | ||||
|     case 4:  GOTO_SCREEN(NozzleOffsetScreen);         break; | ||||
|     #endif | ||||
|     case 5:  GOTO_SCREEN(MaxVelocityScreen);          break; | ||||
|     case 6:  GOTO_SCREEN(DefaultAccelerationScreen);  break; | ||||
|     case 7: | ||||
|       #if ENABLED(JUNCTION_DEVIATION) | ||||
|         GOTO_SCREEN(JunctionDeviationScreen); | ||||
|       #else | ||||
|         GOTO_SCREEN(JerkScreen); | ||||
|       #endif | ||||
|       break; | ||||
|     #if ENABLED(BACKLASH_GCODE) | ||||
|     case 8:  GOTO_SCREEN(BacklashCompensationScreen); break; | ||||
|     #endif | ||||
|     case 9:  GOTO_SCREEN(InterfaceSettingsScreen);  LockScreen::check_passcode(); break; | ||||
|     case 10: GOTO_SCREEN(RestoreFailsafeDialogBox); LockScreen::check_passcode(); break; | ||||
|     #if ENABLED(LIN_ADVANCE) || ENABLED(FILAMENT_RUNOUT_SENSOR) | ||||
|     case 11: GOTO_SCREEN(FilamentMenu); break; | ||||
|     #endif | ||||
|     case 12: GOTO_SCREEN(EndstopStatesScreen); break; | ||||
|     #if HAS_TRINAMIC | ||||
|     case 13: GOTO_SCREEN(StepperCurrentScreen); break; | ||||
|     case 14: GOTO_SCREEN(StepperBumpSensitivityScreen); break; | ||||
|     #endif | ||||
|     case 15: GOTO_SCREEN(DisplayTuningScreen); break; | ||||
|     default: return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,70 @@ | ||||
| /************************ | ||||
|  * alert_dialog_box.cpp * | ||||
|  ************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void AlertDialogBox::onEntry() { | ||||
|   BaseScreen::onEntry(); | ||||
|   sound.play(screen_data.AlertDialogBox.isError ? sad_trombone : twinkle, PLAY_ASYNCHRONOUS); | ||||
| } | ||||
|  | ||||
| void AlertDialogBox::onRedraw(draw_mode_t what) { | ||||
|   if (what & FOREGROUND) { | ||||
|     drawOkayButton(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| void AlertDialogBox::show(const T message) { | ||||
|   drawMessage(message); | ||||
|   storeBackground(); | ||||
|   screen_data.AlertDialogBox.isError = false; | ||||
|   GOTO_SCREEN(AlertDialogBox); | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| void AlertDialogBox::showError(const T message) { | ||||
|   drawMessage(message); | ||||
|   storeBackground(); | ||||
|   screen_data.AlertDialogBox.isError = true; | ||||
|   GOTO_SCREEN(AlertDialogBox); | ||||
| } | ||||
|  | ||||
| void AlertDialogBox::hide() { | ||||
|   if (AT_SCREEN(AlertDialogBox)) | ||||
|     GOTO_PREVIOUS(); | ||||
| } | ||||
|  | ||||
| template void AlertDialogBox::show(const char *); | ||||
| template void AlertDialogBox::show(const progmem_str); | ||||
| template void AlertDialogBox::showError(const char *); | ||||
| template void AlertDialogBox::showError(const progmem_str); | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,72 @@ | ||||
| /************************************ | ||||
|  * backlash_compensation_screen.cpp * | ||||
|  ************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ENABLED(BACKLASH_GCODE) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void BacklashCompensationScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.precision(2).units(PSTR("mm")); | ||||
|   w.heading(                  PSTR("Axis Backlash")); | ||||
|   w.color(x_axis).adjuster(2, PSTR("X:"), getAxisBacklash_mm(X)); | ||||
|   w.color(y_axis).adjuster(4, PSTR("Y:"), getAxisBacklash_mm(Y)); | ||||
|   w.color(z_axis).adjuster(6, PSTR("Z:"), getAxisBacklash_mm(Z)); | ||||
|   #if ENABLED(CALIBRATION_GCODE) | ||||
|   w.button(12, PSTR("Measure automatically")); | ||||
|   #endif | ||||
|   w.color(other).adjuster(8,  PSTR("Smoothing:"), getBacklashSmoothing_mm()); | ||||
|   w.precision(0).units(PSTR("%")) | ||||
|                 .adjuster(10, PSTR("Correction:"), getBacklashCorrection_percent()); | ||||
|   w.precision(2).increments(); | ||||
| } | ||||
|  | ||||
| bool BacklashCompensationScreen::onTouchHeld(uint8_t tag) { | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case  2:  UI_DECREMENT(AxisBacklash_mm, X); break; | ||||
|     case  3:  UI_INCREMENT(AxisBacklash_mm, X); break; | ||||
|     case  4:  UI_DECREMENT(AxisBacklash_mm, Y); break; | ||||
|     case  5:  UI_INCREMENT(AxisBacklash_mm, Y); break; | ||||
|     case  6:  UI_DECREMENT(AxisBacklash_mm, Z); break; | ||||
|     case  7:  UI_INCREMENT(AxisBacklash_mm, Z); break; | ||||
|     case  8:  UI_DECREMENT(BacklashSmoothing_mm); break; | ||||
|     case  9:  UI_INCREMENT(BacklashSmoothing_mm); break; | ||||
|     case  10: UI_DECREMENT_BY(BacklashCorrection_percent, increment*100);  break; | ||||
|     case  11: UI_INCREMENT_BY(BacklashCorrection_percent, increment*100);  break; | ||||
|     #if ENABLED(CALIBRATION_GCODE) | ||||
|     case  12: GOTO_SCREEN(ConfirmAutoCalibrationDialogBox); return true; | ||||
|     #endif | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,342 @@ | ||||
| /************************************** | ||||
|  * base_numeric_adjustment_screen.cpp * | ||||
|  **************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| #ifdef TOUCH_UI_PORTRAIT | ||||
|   #define GRID_COLS 13 | ||||
|   #define GRID_ROWS 10 | ||||
| #else | ||||
|   #define GRID_COLS 18 | ||||
|   #define GRID_ROWS  7 | ||||
| #endif | ||||
|  | ||||
| BaseNumericAdjustmentScreen::widgets_t::widgets_t(draw_mode_t what) : _what(what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.font(font_medium) | ||||
|        .colors(action_btn) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .tag(1).button( BTN_POS(1,10), BTN_SIZE(13,1), F("Back")) | ||||
|     #else | ||||
|        .tag(1).button( BTN_POS(15,7), BTN_SIZE(4,1),  F("Back")) | ||||
|     #endif | ||||
|        .colors(normal_btn); | ||||
|   } | ||||
|  | ||||
|   _line = 1; | ||||
|   _units = PSTR(""); | ||||
| } | ||||
|  | ||||
| BaseNumericAdjustmentScreen::widgets_t &BaseNumericAdjustmentScreen::widgets_t::precision(uint8_t decimals, precision_default_t initial) { | ||||
|   _decimals = decimals; | ||||
|   if (screen_data.BaseNumericAdjustmentScreen.increment == 0) { | ||||
|     screen_data.BaseNumericAdjustmentScreen.increment = 243 + (initial - DEFAULT_LOWEST) - _decimals; | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::heading(const char *label) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.font(font_medium).cmd(COLOR_RGB(bg_text_enabled)); | ||||
|   if (_what & BACKGROUND) { | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       cmd.tag(0).fgcolor(bg_color).button( BTN_POS(1, _line), BTN_SIZE(12,1), progmem_str(label), OPT_FLAT); | ||||
|     #else | ||||
|       cmd.tag(0).fgcolor(bg_color).button( BTN_POS(5, _line), BTN_SIZE(8,1),  progmem_str(label), OPT_FLAT); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   _line++; | ||||
| } | ||||
|  | ||||
| #ifdef TOUCH_UI_PORTRAIT | ||||
|   #ifdef TOUCH_UI_800x480 | ||||
|     #undef EDGE_R | ||||
|     #define EDGE_R 20 | ||||
|   #else | ||||
|     #undef EDGE_R | ||||
|     #define EDGE_R 10 | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::_draw_increment_btn(uint8_t, const uint8_t tag) { | ||||
|   CommandProcessor  cmd; | ||||
|   const char        *label = PSTR("?"); | ||||
|   uint8_t            pos; | ||||
|   uint8_t &          increment = screen_data.BaseNumericAdjustmentScreen.increment; | ||||
|  | ||||
|   if (increment == 0) { | ||||
|     increment = tag; // Set the default value to be the first. | ||||
|   } | ||||
|  | ||||
|   switch (tag) { | ||||
|     case 240: label = PSTR(   ".001"); pos = _decimals - 3; break; | ||||
|     case 241: label = PSTR(   ".01" ); pos = _decimals - 2; break; | ||||
|     case 242: label = PSTR(  "0.1"  ); pos = _decimals - 1; break; | ||||
|     case 243: label = PSTR(  "1"    ); pos = _decimals + 0; break; | ||||
|     case 244: label = PSTR( "10"    ); pos = _decimals + 1; break; | ||||
|     default:  label = PSTR("100"    ); pos = _decimals + 2; break; | ||||
|   } | ||||
|  | ||||
|   cmd.tag(tag) | ||||
|      .colors(increment == tag ? action_btn : normal_btn) | ||||
|   #ifdef TOUCH_UI_PORTRAIT | ||||
|      .font(font_small); | ||||
|   #else | ||||
|      .font(font_medium); | ||||
|   #endif | ||||
|   switch (pos) { | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       case 0: cmd.button( BTN_POS(5,_line), BTN_SIZE(2,1), progmem_str(label)); break; | ||||
|       case 1: cmd.button( BTN_POS(7,_line), BTN_SIZE(2,1), progmem_str(label)); break; | ||||
|       case 2: cmd.button( BTN_POS(9,_line), BTN_SIZE(2,1), progmem_str(label)); break; | ||||
|     #else | ||||
|       case 0: cmd.button( BTN_POS(15,2),    BTN_SIZE(4,1), progmem_str(label)); break; | ||||
|       case 1: cmd.button( BTN_POS(15,3),    BTN_SIZE(4,1), progmem_str(label)); break; | ||||
|       case 2: cmd.button( BTN_POS(15,4),    BTN_SIZE(4,1), progmem_str(label)); break; | ||||
|     #endif | ||||
|   } | ||||
|   cmd.colors(normal_btn); | ||||
| } | ||||
|  | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::increments() { | ||||
|   if (_what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.fgcolor(bg_color) | ||||
|        .tag(0) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .font(font_small).button( BTN_POS(1, _line),  BTN_SIZE(4,1), F("Increment:"), OPT_FLAT); | ||||
|     #else | ||||
|        .font(font_medium).button( BTN_POS(15,1),     BTN_SIZE(4,1), F("Increment:"), OPT_FLAT); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   if (_what & FOREGROUND) { | ||||
|       _draw_increment_btn(_line+1, 245 - _decimals); | ||||
|       _draw_increment_btn(_line+1, 244 - _decimals); | ||||
|       _draw_increment_btn(_line+1, 243 - _decimals); | ||||
|   } | ||||
|  | ||||
|   #ifdef TOUCH_UI_PORTRAIT | ||||
|   _line++; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::adjuster_sram_val(uint8_t tag, const char *label, const char *value, bool is_enabled) { | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   if (_what & BACKGROUND) { | ||||
|     cmd.enabled(1) | ||||
|        .font(font_small) | ||||
|        .fgcolor(_color)            .tag(0).button( BTN_POS(5,_line), BTN_SIZE(5,1), F(""),               OPT_FLAT) | ||||
|        .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .fgcolor(bg_color) .tag(0).button( BTN_POS(1,_line), BTN_SIZE(4,1), (progmem_str) label, OPT_FLAT); | ||||
|   } | ||||
|  | ||||
|   if (_what & FOREGROUND) { | ||||
|     cmd.colors(normal_btn) | ||||
|        .font(font_medium) | ||||
|        .tag(is_enabled ? tag   : 0).enabled(is_enabled).button( BTN_POS(10,_line), BTN_SIZE(2,1),  F("-")) | ||||
|        .tag(is_enabled ? tag+1 : 0).enabled(is_enabled).button( BTN_POS(12,_line), BTN_SIZE(2,1),  F("+")) | ||||
|        .tag(0).font(font_small)                        .text  ( BTN_POS(5,_line),  BTN_SIZE(5,1),  is_enabled ? value : "-"); | ||||
|   } | ||||
|  | ||||
|   _line++; | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::adjuster(uint8_t tag, const char *label, const char *value, bool is_enabled) { | ||||
|   if (_what & BACKGROUND) { | ||||
|     adjuster_sram_val(tag, label, nullptr); | ||||
|   } | ||||
|  | ||||
|   if (_what & FOREGROUND) { | ||||
|     char b[strlen_P(value)+1]; | ||||
|     strcpy_P(b,value); | ||||
|     adjuster_sram_val(tag, label, b, is_enabled); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::adjuster(uint8_t tag, const char *label, float value, bool is_enabled) { | ||||
|   if (_what & BACKGROUND) { | ||||
|     adjuster_sram_val(tag, label, nullptr); | ||||
|   } | ||||
|  | ||||
|   if (_what & FOREGROUND) { | ||||
|     char b[32]; | ||||
|     dtostrf(value, 5, _decimals, b); | ||||
|     strcat_P(b, PSTR(" ")); | ||||
|     strcat_P(b, (const char*) _units); | ||||
|     adjuster_sram_val(tag, label, b, is_enabled); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::button(uint8_t tag, const char *label, bool is_enabled) { | ||||
|   if (_what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.colors(normal_btn) | ||||
|        .tag(is_enabled ? tag   : 0) | ||||
|        .enabled(is_enabled) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .font(font_small) | ||||
|     #else | ||||
|        .font(font_medium) | ||||
|     #endif | ||||
|     .button(BTN_POS(5,_line), BTN_SIZE(9,1), progmem_str(label)); | ||||
|   } | ||||
|  | ||||
|   _line++; | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::text_field(uint8_t tag, const char *label, const char *value, bool is_enabled) { | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   if (_what & BACKGROUND) { | ||||
|     cmd.enabled(1) | ||||
|        .font(font_small) | ||||
|        .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .fgcolor(_color).tag(0).button( BTN_POS(5,_line), BTN_SIZE(9,1), F(""),               OPT_FLAT) | ||||
|        .fgcolor(bg_color) .tag(0).button( BTN_POS(1,_line), BTN_SIZE(4,1), (progmem_str) label, OPT_FLAT); | ||||
|   } | ||||
|  | ||||
|   if (_what & FOREGROUND) { | ||||
|     cmd.colors(normal_btn) | ||||
|        .font(font_medium) | ||||
|        .tag(tag).font(font_small).text ( BTN_POS(5,_line), BTN_SIZE(9,1), is_enabled ? value : "-"); | ||||
|   } | ||||
|  | ||||
|   _line++; | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::two_buttons(uint8_t tag1, const char *label1, uint8_t tag2, const char *label2, bool is_enabled) { | ||||
|   if (_what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.enabled(is_enabled) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .font(font_small) | ||||
|     #else | ||||
|        .font(font_medium) | ||||
|     #endif | ||||
|     .tag(is_enabled ? tag1: 0).button(BTN_POS(5,_line),   BTN_SIZE(4.5,1), progmem_str(label1)) | ||||
|     .tag(is_enabled ? tag2: 0).button(BTN_POS(9.5,_line), BTN_SIZE(4.5,1), progmem_str(label2)); | ||||
|   } | ||||
|  | ||||
|   _line++; | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::toggle(uint8_t tag, const char *label, const char *text, bool value, bool is_enabled) { | ||||
|   if (_what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.fgcolor(bg_color) | ||||
|        .tag(0) | ||||
|        .font(font_small) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .button( BTN_POS(1, _line), BTN_SIZE( 8,1), progmem_str(label), OPT_FLAT); | ||||
|     #else | ||||
|        .button( BTN_POS(1, _line), BTN_SIZE(10,1), progmem_str(label), OPT_FLAT); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   if (_what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.tag(is_enabled ? tag   : 0) | ||||
|        .enabled(is_enabled) | ||||
|        .font(font_small) | ||||
|        .colors(ui_toggle) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       .toggle(BTN_POS( 9,_line), BTN_SIZE(5,1), progmem_str(text), value); | ||||
|     #else | ||||
|       .toggle(BTN_POS(10,_line), BTN_SIZE(4,1), progmem_str(text), value); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   _line++; | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::widgets_t::home_buttons(uint8_t tag) { | ||||
|   if (_what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.fgcolor(bg_color) | ||||
|        .tag(0) | ||||
|        .font(font_small) | ||||
|        .button( BTN_POS(1, _line),  BTN_SIZE(4,1), F("Home:"), OPT_FLAT); | ||||
|   } | ||||
|  | ||||
|   if (_what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .font(font_small) | ||||
|     #else | ||||
|        .font(font_medium) | ||||
|     #endif | ||||
|        .tag(tag+0).button(BTN_POS(5,_line),  BTN_SIZE(2,1), F("X")) | ||||
|        .tag(tag+1).button(BTN_POS(7,_line),  BTN_SIZE(2,1), F("Y")) | ||||
|        .tag(tag+2).button(BTN_POS(9,_line),  BTN_SIZE(2,1), F("Z")) | ||||
|        .tag(tag+3).button(BTN_POS(11,_line), BTN_SIZE(3,1), F("All")); | ||||
|   } | ||||
|  | ||||
|   _line++; | ||||
| } | ||||
|  | ||||
| void BaseNumericAdjustmentScreen::onEntry() { | ||||
|   screen_data.BaseNumericAdjustmentScreen.increment = 0; // This will force the increment to be picked while drawing. | ||||
|   BaseScreen::onEntry(); | ||||
| } | ||||
|  | ||||
| bool BaseNumericAdjustmentScreen::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1:           GOTO_PREVIOUS();                            return true; | ||||
|     case 240 ... 245: screen_data.BaseNumericAdjustmentScreen.increment = tag; break; | ||||
|     default:          return current_screen.onTouchHeld(tag); | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| float BaseNumericAdjustmentScreen::getIncrement() { | ||||
|   switch (screen_data.BaseNumericAdjustmentScreen.increment) { | ||||
|     case 240: return   0.001; | ||||
|     case 241: return   0.01; | ||||
|     case 242: return   0.1; | ||||
|     case 243: return   1.0; | ||||
|     case 244: return  10.0; | ||||
|     case 245: return 100.0; | ||||
|     default:  return   0.0; | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,83 @@ | ||||
| /******************* | ||||
|  * base_screen.cpp * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void BaseScreen::onEntry() { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.set_button_style_callback(buttonStyleCallback); | ||||
|   UIScreen::onEntry(); | ||||
| } | ||||
|  | ||||
| bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t &style, uint16_t &options, bool post) { | ||||
|   if (post) { | ||||
|     cmd.colors(normal_btn); | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   #ifdef LCD_TIMEOUT_TO_STATUS | ||||
|     if (EventLoop::get_pressed_tag() != 0) { | ||||
|       reset_menu_timeout(); | ||||
|     } | ||||
|   #endif | ||||
|  | ||||
|   if (tag != 0 && EventLoop::get_pressed_tag() == tag) { | ||||
|     options = OPT_FLAT; | ||||
|   } | ||||
|  | ||||
|   if (style & cmd.STYLE_DISABLED) { | ||||
|     cmd.tag(0); | ||||
|     style &= ~cmd.STYLE_DISABLED; | ||||
|     cmd.colors(disabled_btn); | ||||
|     return true; // Call me again to reset the colors | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| void BaseScreen::onIdle() { | ||||
|   #ifdef LCD_TIMEOUT_TO_STATUS | ||||
|     const uint32_t elapsed = millis() - last_interaction; | ||||
|     if (elapsed > uint32_t(LCD_TIMEOUT_TO_STATUS) * 1000) { | ||||
|       reset_menu_timeout(); | ||||
|       GOTO_SCREEN(StatusScreen); | ||||
|     } | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void BaseScreen::reset_menu_timeout() { | ||||
|   #ifdef LCD_TIMEOUT_TO_STATUS | ||||
|     last_interaction = millis(); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #ifdef LCD_TIMEOUT_TO_STATUS | ||||
|   uint32_t BaseScreen::last_interaction; | ||||
| #endif | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,137 @@ | ||||
| /***************************** | ||||
|  * bio_advanced_settings.cpp * | ||||
|  *****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void AdvancedSettingsMenu::onRedraw(draw_mode_t what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.colors(normal_btn) | ||||
|        .font(Theme::font_medium) | ||||
|     #define GRID_ROWS 9 | ||||
|     #define GRID_COLS 2 | ||||
|  | ||||
|       .tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), F("Display")) | ||||
|       #if HAS_TRINAMIC | ||||
|        .enabled(1) | ||||
|       #else | ||||
|        .enabled(0) | ||||
|       #endif | ||||
|       .tag(3) .button( BTN_POS(1,2), BTN_SIZE(1,1), F("Motor mA")) | ||||
|       #if HAS_TRINAMIC | ||||
|        .enabled(1) | ||||
|       #else | ||||
|        .enabled(0) | ||||
|       #endif | ||||
|       .tag(4) .button( BTN_POS(1,3), BTN_SIZE(1,1), F("Bump Sense")) | ||||
|       .tag(5) .button( BTN_POS(1,4), BTN_SIZE(1,1), F("Endstops")) | ||||
|       #if HOTENDS > 1 | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(6) .button( BTN_POS(1,5), BTN_SIZE(1,1), F("Nozzle Offset")) | ||||
|  | ||||
|  | ||||
|       .tag(7) .button( BTN_POS(2,1), BTN_SIZE(1,1), F("Steps/mm")) | ||||
|       .tag(8) .button( BTN_POS(2,2), BTN_SIZE(1,1), F("Velocity ")) | ||||
|       .tag(9) .button( BTN_POS(2,3), BTN_SIZE(1,1), F("Acceleration")) | ||||
|       #if ENABLED(JUNCTION_DEVIATION) | ||||
|         .tag(10) .button( BTN_POS(2,4), BTN_SIZE(1,1), F("Junc Dev")) | ||||
|       #else | ||||
|         .tag(10) .button( BTN_POS(2,4), BTN_SIZE(1,1), F("Jerk")) | ||||
|       #endif | ||||
|       #if ENABLED(BACKLASH_GCODE) | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(11) .button( BTN_POS(2,5), BTN_SIZE(1,1), F("Backlash")) | ||||
|       #if ENABLED(LIN_ADVANCE) | ||||
|       .enabled(1) | ||||
|       #else | ||||
|       .enabled(0) | ||||
|       #endif | ||||
|       .tag(12) .button( BTN_POS(1,6), BTN_SIZE(2,1), F("Linear Advance")) | ||||
|       .tag(13) .button( BTN_POS(1,7), BTN_SIZE(2,1), F("Interface Settings")) | ||||
|       .tag(14) .button( BTN_POS(1,8), BTN_SIZE(2,1), F("Restore Factory Defaults")) | ||||
|       .colors(action_btn) | ||||
|       .tag(1). button( BTN_POS(1,9), BTN_SIZE(2,1), F("Back")); | ||||
|     #undef GRID_COLS | ||||
|     #undef GRID_ROWS | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) { | ||||
|   using namespace ExtUI; | ||||
|  | ||||
|   switch (tag) { | ||||
|     case 1: SaveSettingsDialogBox::promptToSaveSettings(); break; | ||||
|     case 2: GOTO_SCREEN(DisplayTuningScreen);              break; | ||||
|     #if HAS_TRINAMIC | ||||
|     case 3: GOTO_SCREEN(StepperCurrentScreen);             break; | ||||
|     case 4: GOTO_SCREEN(StepperBumpSensitivityScreen);     break; | ||||
|     #endif | ||||
|     case 5: GOTO_SCREEN(EndstopStatesScreen);              break; | ||||
|     #if HOTENDS > 1 | ||||
|     case 6: GOTO_SCREEN(NozzleOffsetScreen);               break; | ||||
|     #endif | ||||
|  | ||||
|     case 7: GOTO_SCREEN(StepsScreen);                      break; | ||||
|     case 8: GOTO_SCREEN(MaxVelocityScreen);                break; | ||||
|     case 9: GOTO_SCREEN(DefaultAccelerationScreen);        break; | ||||
|     case 10: | ||||
|       #if ENABLED(JUNCTION_DEVIATION) | ||||
|         GOTO_SCREEN(JunctionDeviationScreen); | ||||
|       #else | ||||
|         GOTO_SCREEN(JerkScreen); | ||||
|       #endif | ||||
|       break; | ||||
|     #if ENABLED(BACKLASH_GCODE) | ||||
|     case 11: GOTO_SCREEN(BacklashCompensationScreen);      break; | ||||
|     #endif | ||||
|     #if ENABLED(LIN_ADVANCE) | ||||
|     case 12: GOTO_SCREEN(LinearAdvanceScreen);             break; | ||||
|     #endif | ||||
|     case 13: GOTO_SCREEN(InterfaceSettingsScreen);         break; | ||||
|     case 14: GOTO_SCREEN(RestoreFailsafeDialogBox);        break; | ||||
|  | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,56 @@ | ||||
| /**************************** | ||||
|  * bio_confirm_home_xyz.cpp * | ||||
|  ****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
|  | ||||
| void BioConfirmHomeE::onRedraw(draw_mode_t) { | ||||
|   drawMessage(F("About to re-home plunger and auto-level. Remove syringe prior to proceeding.\n\nContinue?")); | ||||
|   drawYesNoButtons(1); | ||||
| } | ||||
|  | ||||
| bool BioConfirmHomeE::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: | ||||
|       SpinnerDialogBox::enqueueAndWait_P(F( | ||||
|         "G112\n"                            /* Home extruder */ | ||||
|         LULZBOT_AXIS_LEVELING_COMMANDS      /* Level X axis */ | ||||
|         "G0 X115 Z50 F6000\n"               /* Goto loading position */ | ||||
|         "M400\n"                            /* Wait for moves to finish */ | ||||
|         "M18 X Y"                           /* Unlock motors */ | ||||
|       )); | ||||
|       current_screen.forget(); | ||||
|       break; | ||||
|     case 2: | ||||
|       GOTO_SCREEN(StatusScreen); | ||||
|       break; | ||||
|     default: | ||||
|       return DialogBoxBaseClass::onTouchEnd(tag); | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,53 @@ | ||||
| /**************************** | ||||
|  * bio_confirm_home_xyz.cpp * | ||||
|  ****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
|  | ||||
| void BioConfirmHomeXYZ::onRedraw(draw_mode_t) { | ||||
|   drawMessage(F("About to home to loading position.\nEnsure the top and the bed of the printer are clear.\n\nContinue?")); | ||||
|   drawYesNoButtons(1); | ||||
| } | ||||
|  | ||||
| bool BioConfirmHomeXYZ::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: | ||||
|       SpinnerDialogBox::enqueueAndWait_P(F( | ||||
|         "G28 X Y Z\n"             /* Home all axis */ | ||||
|         "G0 X115 Z50 F6000"       /* Move to park position */ | ||||
|       )); | ||||
|       current_screen.forget(); | ||||
|       break; | ||||
|     case 2: | ||||
|       GOTO_SCREEN(StatusScreen); | ||||
|       break; | ||||
|     default: | ||||
|       return DialogBoxBaseClass::onTouchEnd(tag); | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,79 @@ | ||||
| /********************* | ||||
|  * bio_main_menu.cpp * | ||||
|  *********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void MainMenu::onRedraw(draw_mode_t what) { | ||||
|   #define GRID_ROWS 8 | ||||
|   #define GRID_COLS 2 | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .font(font_large).text( BTN_POS(1,1), BTN_SIZE(2,1), F("Main Menu")) | ||||
|        .colors(normal_btn) | ||||
|        .font(font_medium) | ||||
|        .tag(2).button( BTN_POS(1,2), BTN_SIZE(2,1), F("Load Syringe")) | ||||
|        .tag(3).button( BTN_POS(1,3), BTN_SIZE(2,1), F("Unlock XY Axis")) | ||||
|        .tag(4).button( BTN_POS(1,4), BTN_SIZE(2,1), F("Bed Temperature")) | ||||
|        .tag(5).button( BTN_POS(1,5), BTN_SIZE(2,1), F("Interface Settings")) | ||||
|        .tag(6).button( BTN_POS(1,6), BTN_SIZE(2,1), F("Advanced Settings")) | ||||
|        .tag(7).button( BTN_POS(1,7), BTN_SIZE(2,1), F("About Printer")) | ||||
|        .colors(action_btn) | ||||
|        .tag(1).button( BTN_POS(1,8), BTN_SIZE(2,1), F("Back")); | ||||
|   } | ||||
|  | ||||
|   #undef GRID_COLS | ||||
|   #undef GRID_ROWS | ||||
| } | ||||
|  | ||||
| bool MainMenu::onTouchEnd(uint8_t tag) { | ||||
|   using namespace ExtUI; | ||||
|  | ||||
|   switch (tag) { | ||||
|     case 1: SaveSettingsDialogBox::promptToSaveSettings();                               break; | ||||
|     case 2: GOTO_SCREEN(BioConfirmHomeXYZ);                                              break; | ||||
|     case 3: StatusScreen::unlockMotors();                                                break; | ||||
|     case 4:  GOTO_SCREEN(TemperatureScreen);                                             break; | ||||
|     case 5: GOTO_SCREEN(InterfaceSettingsScreen);                                        break; | ||||
|     case 6: GOTO_SCREEN(AdvancedSettingsMenu);                                           break; | ||||
|     case 7: GOTO_SCREEN(AboutScreen);                                                    break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,75 @@ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   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 file was auto-generated using "svg2cpp.pl" | ||||
|  * | ||||
|  * The encoding consists of x,y pairs with the min and max scaled to | ||||
|  * 0x0000 and 0xFFFE. A single 0xFFFF in the data stream indicates the | ||||
|  * start of a new closed path. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| constexpr float x_min = 0.000000; | ||||
|  | ||||
| constexpr float x_max = 272.000000; | ||||
|  | ||||
| constexpr float y_min = 0.000000; | ||||
|  | ||||
| constexpr float y_max = 480.000000; | ||||
|  | ||||
| const PROGMEM uint16_t z_neg[] = {0xC9B1, 0x96B3, 0xD990, 0x96B3, 0xD990, 0xA8D0, 0xE17F, 0xA8D0, 0xD1A0, 0xB1DF, 0xC1C2, 0xA8D0, 0xC9B1, 0xA8D0, 0xC9B1, 0x96B3}; | ||||
|  | ||||
| const PROGMEM uint16_t z_pos[] = {0xC9B1, 0x8DA4, 0xD990, 0x8DA4, 0xD990, 0x7B86, 0xE17F, 0x7B86, 0xD1A0, 0x7277, 0xC1C2, 0x7B86, 0xC9B1, 0x7B86, 0xC9B1, 0x8DA4}; | ||||
|  | ||||
| const PROGMEM uint16_t y_neg[] = {0x5037, 0x9979, 0x6264, 0x9979, 0x5529, 0xA92A, 0x5E3F, 0xA92A, 0x4575, 0xB103, 0x39E6, 0xA92A, 0x42FC, 0xA92A, 0x5037, 0x9979}; | ||||
|  | ||||
| const PROGMEM uint16_t y_pos[] = {0x5D72, 0x89C7, 0x6F9F, 0x89C7, 0x7CDA, 0x7A15, 0x85F0, 0x7A15, 0x7A61, 0x723D, 0x6197, 0x7A15, 0x6AAD, 0x7A15, 0x5D72, 0x89C7}; | ||||
|  | ||||
| const PROGMEM uint16_t x_neg[] = {0x513D, 0x8DB3, 0x4AA0, 0x958C, 0x2647, 0x958C, 0x22F8, 0x9979, 0x1769, 0x91A0, 0x3033, 0x89C7, 0x2CE4, 0x8DB3, 0x513D, 0x8DB3}; | ||||
|  | ||||
| const PROGMEM uint16_t x_pos[] = {0x7566, 0x8DB3, 0x6EC9, 0x958C, 0x9322, 0x958C, 0x8FD4, 0x9979, 0xA89E, 0x91A0, 0x9D0E, 0x89C7, 0x99C0, 0x8DB3, 0x7566, 0x8DB3}; | ||||
|  | ||||
| const PROGMEM uint16_t syringe_fluid[] = {0x7D1D, 0x4A0F, 0x87FC, 0x4C0E, 0x8CF4, 0x4C0E, 0x9801, 0x4A0F, 0x9801, 0x1AA2, 0x7D1D, 0x1AA2, 0x7D1D, 0x4A0F}; | ||||
|  | ||||
| const PROGMEM uint16_t syringe[] = {0x83C2, 0x42AA, 0x83C2, 0x43FF, 0x8D2C, 0x43FF, 0x8D2C, 0x42AA, 0xFFFF, 0x83C2, 0x3D54, 0x83C2, 0x3EAA, 0x8D2C, 0x3EAA, 0x8D2C, 0x3D54, 0xFFFF, 0x83C2, 0x37FF, 0x83C2, 0x3954, 0x8D2C, 0x3954, 0x8D2C, 0x37FF, 0xFFFF, 0x83C2, 0x32AA, 0x83C2, 0x33FF, 0x8D2C, 0x33FF, 0x8D2C, 0x32AA, 0xFFFF, 0x83C2, 0x2D54, 0x83C2, 0x2EAA, 0x8D2C, 0x2EAA, 0x8D2C, 0x2D54, 0xFFFF, 0x83C2, 0x27FF, 0x83C2, 0x2955, 0x8D2C, 0x2955, 0x8D2C, 0x27FF, 0xFFFF, 0x83C2, 0x22AA, 0x83C2, 0x23FF, 0x8D2C, 0x23FF, 0x8D2C, 0x22AA, 0xFFFF, 0x7AC7, 0x0F4B, 0x7AC7, 0x134A, 0x855B, 0x134A, 0x855B, 0x1949, 0x7AC7, 0x1949, 0x7AC7, 0x4B40, 0x855B, 0x4D40, 0x855B, 0x533F, 0x88E2, 0x533F, 0x88E2, 0x653C, 0x8C69, 0x673C, 0x8C69, 0x533F, 0x8FF0, 0x533F, 0x8FF0, 0x4D40, 0x9A85, 0x4B40, 0x9A85, 0x1949, 0x8FF0, 0x1949, 0x8FF0, 0x134A, 0x9A85, 0x134A, 0x9A85, 0x0F4B, 0xFFFF, 0x88E2, 0x134A, 0x8C69, 0x134A, 0x8C69, 0x1949, 0x88E2, 0x1949, 0x88E2, 0x134A, 0xFFFF, 0x7E4D, 0x1B49, 0x96FE, 0x1B49, 0x96FE, 0x4941, 0x8C69, 0x4B40, 0x88E2, 0x4B40, 0x7E4D, 0x4941, 0x7E4D, 0x1B49}; | ||||
|  | ||||
| const PROGMEM uint16_t syringe_outline[] = {0x7AC7, 0x0F4B, 0x7AC7, 0x134A, 0x855B, 0x134A, 0x855B, 0x1949, 0x7AC7, 0x1949, 0x7AC7, 0x4B40, 0x855B, 0x4D40, 0x855B, 0x533F, 0x88E2, 0x533F, 0x88E2, 0x653C, 0x8C69, 0x673C, 0x8C69, 0x533F, 0x8FF0, 0x533F, 0x8FF0, 0x4D40, 0x9A85, 0x4B40, 0x9A85, 0x1949, 0x8FF0, 0x1949, 0x8FF0, 0x134A, 0x9A85, 0x134A, 0x9A85, 0x0F4B, 0x7AC7, 0x0F4B}; | ||||
|  | ||||
| const PROGMEM uint16_t padlock[] = {0x645A, 0x8017, 0x5F9E, 0x80A1, 0x5BBA, 0x821B, 0x5911, 0x844A, 0x580A, 0x86F7, 0x580A, 0x8931, 0x5970, 0x8A98, 0x5C49, 0x8A98, 0x5DB0, 0x8931, 0x5DB0, 0x8703, 0x5E3C, 0x858E, 0x5FAA, 0x845F, 0x61C5, 0x8394, 0x645A, 0x834A, 0x66F0, 0x8394, 0x690C, 0x845F, 0x6A7A, 0x858D, 0x6B07, 0x8703, 0x6B07, 0x8F23, 0x57C8, 0x8F23, 0x551E, 0x8FC3, 0x5404, 0x9145, 0x5404, 0x9C8F, 0x551E, 0x9E11, 0x57C8, 0x9EB1, 0x70EE, 0x9EB1, 0x7398, 0x9E11, 0x74B2, 0x9C8F, 0x74B2, 0x9145, 0x7398, 0x8FC3, 0x70EE, 0x8F23, 0x70AC, 0x86FA, 0x6FA5, 0x844A, 0x6CFD, 0x821B, 0x6917, 0x80A1}; | ||||
|  | ||||
| const PROGMEM uint16_t home_z[] = {0xD6C9, 0x80CC, 0xBB53, 0x905B, 0xC231, 0x905B, 0xC231, 0x9FEB, 0xCFEC, 0x9FEB, 0xCFEC, 0x9823, 0xDDA7, 0x9823, 0xDDA7, 0x9FEB, 0xEB62, 0x9FEB, 0xEB62, 0x905B, 0xF240, 0x905B, 0xE7A3, 0x8A58, 0xE7A3, 0x82CD, 0xE0C6, 0x82CD, 0xE0C6, 0x8674}; | ||||
|  | ||||
| const PROGMEM uint16_t home_e[] = {0xB94F, 0x25AA, 0x9DD8, 0x353A, 0xA4B6, 0x353A, 0xA4B6, 0x44C9, 0xB271, 0x44C9, 0xB271, 0x3D02, 0xC02C, 0x3D02, 0xC02C, 0x44C9, 0xCDE7, 0x44C9, 0xCDE7, 0x353A, 0xD4C5, 0x353A, 0xCA28, 0x2F36, 0xCA28, 0x27AB, 0xC34B, 0x27AB, 0xC34B, 0x2B53}; | ||||
|  | ||||
| const PROGMEM uint16_t bed_icon[] = {0x1764, 0x2C4C, 0x6135, 0x2C4C, 0x6135, 0x40A8, 0x1764, 0x40A8}; | ||||
|  | ||||
| const PROGMEM uint16_t actual_temp[] = {0x1764, 0x466F, 0x6135, 0x466F, 0x6135, 0x5ACB, 0x1764, 0x5ACB}; | ||||
|  | ||||
| const PROGMEM uint16_t target_temp[] = {0x1764, 0x1228, 0x6135, 0x1228, 0x6135, 0x2684, 0x1764, 0x2684}; | ||||
|  | ||||
| const PROGMEM uint16_t fine_label[] = {0x1AA7, 0xC6D2, 0x9387, 0xC6D2, 0x9387, 0xD316, 0x1AA7, 0xD316}; | ||||
|  | ||||
| const PROGMEM uint16_t fine_toggle[] = {0x9C10, 0xC6D2, 0xE4A3, 0xC6D2, 0xE4A3, 0xD316, 0x9C10, 0xD316}; | ||||
|  | ||||
| const PROGMEM uint16_t usb_btn[] = {0x0B68, 0xE880, 0x7B1A, 0xE880, 0x7B1A, 0xF94B, 0x0B68, 0xF94B, 0x0B68, 0xE880}; | ||||
|  | ||||
| const PROGMEM uint16_t menu_btn[] = {0x84E3, 0xE880, 0xF495, 0xE880, 0xF495, 0xF94B, 0x84E3, 0xF94B, 0x84E3, 0xE880}; | ||||
|  | ||||
| const PROGMEM uint16_t e_pos[] = {0xC9B1, 0x3B2D, 0xD990, 0x3B2D, 0xD990, 0x4D4B, 0xE17F, 0x4D4B, 0xD1A0, 0x565A, 0xC1C2, 0x4D4B, 0xC9B1, 0x4D4B, 0xC9B1, 0x3B2D}; | ||||
|  | ||||
| const PROGMEM uint16_t e_neg[] = {0xC9B1, 0x321E, 0xD990, 0x321E, 0xD990, 0x2000, 0xE17F, 0x2000, 0xD1A0, 0x16F1, 0xC1C2, 0x2000, 0xC9B1, 0x2000, 0xC9B1, 0x321E}; | ||||
| @@ -0,0 +1,155 @@ | ||||
| /******************************* | ||||
|  * bio_printing_dialog_box.cpp * | ||||
|  *******************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| #include "../ftdi_eve_lib/extras/circular_progress.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| #define GRID_COLS 2 | ||||
| #define GRID_ROWS 9 | ||||
|  | ||||
| void BioPrintingDialogBox::draw_status_message(draw_mode_t what, const char* message) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(COLOR_RGB(bg_text_enabled)); | ||||
|     draw_text_box(cmd, BTN_POS(1,2), BTN_SIZE(2,2), message, OPT_CENTER, font_large); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::draw_progress(draw_mode_t what) { | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.font(font_large) | ||||
|        .text(BTN_POS(1,1), BTN_SIZE(2,2), isPrinting() ? F("Printing...") : F("Finished.")) | ||||
|        .tag(1) | ||||
|        .font(font_xlarge); | ||||
|  | ||||
|     draw_circular_progress(cmd, BTN_POS(1,4), BTN_SIZE(2,3), getProgress_percent(), theme_dark, theme_darkest); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::draw_time_remaining(draw_mode_t what) { | ||||
|   if (what & FOREGROUND) { | ||||
|     const uint32_t elapsed = getProgress_seconds_elapsed(); | ||||
|     const uint8_t hrs = elapsed/3600; | ||||
|     const uint8_t min = (elapsed/60)%60; | ||||
|  | ||||
|     char time_str[10]; | ||||
|     sprintf_P(time_str, PSTR("%02dh %02dm"), hrs, min); | ||||
|  | ||||
|     CommandProcessor cmd; | ||||
|     cmd.font(font_large) | ||||
|        .text(BTN_POS(1,7), BTN_SIZE(2,2), time_str); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::draw_interaction_buttons(draw_mode_t what) { | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.colors(normal_btn) | ||||
|        .font(font_medium) | ||||
|        .colors(isPrinting() ? action_btn : normal_btn) | ||||
|        .tag(2).button(BTN_POS(1,9), BTN_SIZE(1,1), F("Menu")) | ||||
|         #if ENABLED(SDSUPPORT) | ||||
|           .enabled(isPrinting() ? isPrintingFromMedia() : 1) | ||||
|         #else | ||||
|           .enabled(isPrinting() ? 0 : 1) | ||||
|         #endif | ||||
|        .tag(3) | ||||
|        .colors(isPrinting() ? normal_btn : action_btn) | ||||
|        .button( BTN_POS(2,9), BTN_SIZE(1,1), isPrinting() ? F("Cancel") : F("Back")); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::onRedraw(draw_mode_t what) { | ||||
|   if (what & FOREGROUND) { | ||||
|     draw_progress(FOREGROUND); | ||||
|     draw_time_remaining(FOREGROUND); | ||||
|     draw_interaction_buttons(FOREGROUND); | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool BioPrintingDialogBox::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_SCREEN(FeedratePercentScreen); break; | ||||
|     case 2: GOTO_SCREEN(TuneMenu); break; | ||||
|     case 3: | ||||
|      if (isPrinting()) { | ||||
|        GOTO_SCREEN(ConfirmAbortPrintDialogBox); | ||||
|      } else { | ||||
|        GOTO_SCREEN(StatusScreen); | ||||
|      } | ||||
|      break; | ||||
|     default: return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::setStatusMessage(progmem_str message) { | ||||
|   char buff[strlen_P((const char * const)message)+1]; | ||||
|   strcpy_P(buff, (const char * const) message); | ||||
|   setStatusMessage(buff); | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::setStatusMessage(const char* message) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(CMD_DLSTART) | ||||
|      .cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|      .cmd(CLEAR(true,true,true)); | ||||
|  | ||||
|   draw_status_message(BACKGROUND, message); | ||||
|   draw_progress(BACKGROUND); | ||||
|   draw_time_remaining(BACKGROUND); | ||||
|   draw_interaction_buttons(BACKGROUND); | ||||
|   storeBackground(); | ||||
|  | ||||
|   #ifdef UI_FRAMEWORK_DEBUG | ||||
|     SERIAL_ECHO_START(); | ||||
|     SERIAL_ECHOLNPAIR("New status message: ", message); | ||||
|   #endif | ||||
|  | ||||
|   if (AT_SCREEN(BioPrintingDialogBox)) { | ||||
|     current_screen.onRefresh(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::onIdle() { | ||||
|   if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) { | ||||
|     onRefresh(); | ||||
|     refresh_timer.start(); | ||||
|   } | ||||
|   BaseScreen::onIdle(); | ||||
| } | ||||
|  | ||||
| void BioPrintingDialogBox::show() { | ||||
|   GOTO_SCREEN(BioPrintingDialogBox); | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,349 @@ | ||||
| /************************* | ||||
|  * bio_status_screen.cpp * | ||||
|  *************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| #include "../ftdi_eve_lib/extras/poly_ui.h" | ||||
| #include "bio_printer_ui.h" | ||||
|  | ||||
| #define E_TRAVEL_LIMIT 60 | ||||
|  | ||||
| #define GRID_COLS 2 | ||||
| #define GRID_ROWS 9 | ||||
|  | ||||
| #define POLY(A) PolyUI::poly_reader_t(A, sizeof(A)/sizeof(A[0])) | ||||
|  | ||||
| #if ENABLED(SDSUPPORT) && defined(LULZBOT_MANUAL_USB_STARTUP) | ||||
|   #include "../../../../sd/cardreader.h" | ||||
| #endif | ||||
|  | ||||
| const uint8_t shadow_depth = 5; | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
| using namespace ExtUI; | ||||
|  | ||||
| float StatusScreen::increment; | ||||
| bool  StatusScreen::jog_xy; | ||||
| bool  StatusScreen::fine_motion; | ||||
|  | ||||
| void StatusScreen::unlockMotors() { | ||||
|   injectCommands_P(PSTR("M84 XY")); | ||||
|   jog_xy = false; | ||||
| } | ||||
|  | ||||
| void StatusScreen::draw_temperature(draw_mode_t what) { | ||||
|   CommandProcessor cmd; | ||||
|   PolyUI ui(cmd, what); | ||||
|  | ||||
|   int16_t x, y, h, v; | ||||
|  | ||||
|   cmd.tag(15); | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|     cmd.cmd(COLOR_RGB(bg_color)); | ||||
|  | ||||
|     // Draw touch surfaces | ||||
|     ui.bounds(POLY(target_temp), x, y, h, v); | ||||
|     cmd.rectangle(x, y, h, v); | ||||
|     ui.bounds(POLY(actual_temp), x, y, h, v); | ||||
|     cmd.rectangle(x, y, h, v); | ||||
|     ui.bounds(POLY(bed_icon), x, y, h, v); | ||||
|     cmd.rectangle(x, y, h, v); | ||||
|  | ||||
|     // Draw bed icon | ||||
|     cmd.cmd(BITMAP_SOURCE(Bed_Heat_Icon_Info)) | ||||
|        .cmd(BITMAP_LAYOUT(Bed_Heat_Icon_Info)) | ||||
|        .cmd(BITMAP_SIZE  (Bed_Heat_Icon_Info)) | ||||
|        .cmd(COLOR_RGB(shadow_rgb)) | ||||
|        .icon (x + 2, y + 2, h, v, Bed_Heat_Icon_Info, icon_scale * 2) | ||||
|        .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .icon (x, y, h, v, Bed_Heat_Icon_Info, icon_scale * 2); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     char bed_str[15]; | ||||
|  | ||||
|     cmd.font(font_xlarge) | ||||
|        .cmd(COLOR_RGB(bg_text_enabled)); | ||||
|  | ||||
|     if (!isHeaterIdle(BED) && getTargetTemp_celsius(BED) > 0) { | ||||
|       sprintf_P(bed_str, PSTR("%-3d C"), ROUND(getTargetTemp_celsius(BED))); | ||||
|       ui.bounds(POLY(target_temp), x, y, h, v); | ||||
|       cmd.text(x, y, h, v, bed_str); | ||||
|     } | ||||
|  | ||||
|     sprintf_P(bed_str, PSTR("%-3d C"), ROUND(getActualTemp_celsius(BED))); | ||||
|     ui.bounds(POLY(actual_temp), x, y, h, v); | ||||
|     cmd.text(x, y, h, v, bed_str); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void StatusScreen::draw_syringe(draw_mode_t what) { | ||||
|   int16_t x, y, h, v; | ||||
|   const float fill_level = 1.0 - min(1.0, max(0.0, getAxisPosition_mm(E0) / E_TRAVEL_LIMIT)); | ||||
|   const bool  e_homed = isAxisPositionKnown(E0); | ||||
|  | ||||
|   CommandProcessor cmd; | ||||
|   PolyUI ui(cmd, what); | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|     // Paint the shadow for the syringe | ||||
|     ui.color(shadow_rgb); | ||||
|     ui.shadow(POLY(syringe_outline), shadow_depth); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND && e_homed) { | ||||
|     // Paint the syringe icon | ||||
|     ui.color(syringe_rgb); | ||||
|     ui.fill(POLY(syringe_outline)); | ||||
|  | ||||
|     ui.color(fill_rgb); | ||||
|     ui.bounds(POLY(syringe_fluid), x, y, h, v); | ||||
|     cmd.cmd(SAVE_CONTEXT()); | ||||
|     cmd.cmd(SCISSOR_XY(x,y + v * (1.0 - fill_level))); | ||||
|     cmd.cmd(SCISSOR_SIZE(h,  v *        fill_level)); | ||||
|     ui.fill(POLY(syringe_fluid), false); | ||||
|     cmd.cmd(RESTORE_CONTEXT()); | ||||
|  | ||||
|     ui.color(stroke_rgb); | ||||
|     ui.fill(POLY(syringe)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void StatusScreen::draw_arrows(draw_mode_t what) { | ||||
|   const bool  e_homed = isAxisPositionKnown(E0); | ||||
|   const bool  z_homed = isAxisPositionKnown(Z); | ||||
|  | ||||
|   CommandProcessor cmd; | ||||
|   PolyUI ui(cmd, what); | ||||
|  | ||||
|   ui.button_fill  (fill_rgb); | ||||
|   ui.button_stroke(stroke_rgb, 28); | ||||
|   ui.button_shadow(shadow_rgb, shadow_depth); | ||||
|  | ||||
|   if ((what & BACKGROUND) || jog_xy) { | ||||
|     ui.button(1, POLY(x_neg)); | ||||
|     ui.button(2, POLY(x_pos)); | ||||
|     ui.button(3, POLY(y_neg)); | ||||
|     ui.button(4, POLY(y_pos)); | ||||
|   } | ||||
|  | ||||
|   if ((what & BACKGROUND) || z_homed) { | ||||
|     ui.button(5, POLY(z_neg)); | ||||
|     ui.button(6, POLY(z_pos)); | ||||
|   } | ||||
|  | ||||
|   if ((what & BACKGROUND) || e_homed) { | ||||
|     ui.button(7, POLY(e_neg)); | ||||
|     ui.button(8, POLY(e_pos)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void StatusScreen::draw_fine_motion(draw_mode_t what) { | ||||
|   int16_t x, y, h, v; | ||||
|   CommandProcessor cmd; | ||||
|   PolyUI ui(cmd, what); | ||||
|  | ||||
|   cmd.font(font_medium) | ||||
|      .tag(16); | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|  | ||||
|     ui.bounds(POLY(fine_label), x, y, h, v); | ||||
|     cmd.cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .text(x, y, h, v, F("Fine motion:")); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     ui.bounds(POLY(fine_toggle), x, y, h, v); | ||||
|     cmd.colors(ui_toggle) | ||||
|        .toggle(x, y, h, v, F("no\xFFyes"), fine_motion); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void StatusScreen::draw_overlay_icons(draw_mode_t what) { | ||||
|   const bool  e_homed = isAxisPositionKnown(E0); | ||||
|   const bool  z_homed = isAxisPositionKnown(Z); | ||||
|  | ||||
|   CommandProcessor cmd; | ||||
|   PolyUI ui(cmd, what); | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     ui.button_fill  (fill_rgb); | ||||
|     ui.button_stroke(stroke_rgb, 28); | ||||
|     ui.button_shadow(shadow_rgb, shadow_depth); | ||||
|  | ||||
|     if (!jog_xy) { | ||||
|       ui.button(12, POLY(padlock)); | ||||
|     } | ||||
|  | ||||
|     if (!e_homed) { | ||||
|       ui.button(13, POLY(home_e)); | ||||
|     } | ||||
|  | ||||
|     if (!z_homed) { | ||||
|       ui.button(14, POLY(home_z)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void StatusScreen::draw_buttons(draw_mode_t) { | ||||
|   const bool has_media = isMediaInserted() && !isPrintingFromMedia(); | ||||
|  | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   cmd.font(font_medium) | ||||
|      .colors(normal_btn) | ||||
|     #if ENABLED(USB_FLASH_DRIVE_SUPPORT) && defined(LULZBOT_MANUAL_USB_STARTUP) | ||||
|       .enabled(!Sd2Card::ready() || has_media) | ||||
|     #else | ||||
|       .enabled(has_media) | ||||
|     #endif | ||||
|      .colors(has_media ? action_btn : normal_btn) | ||||
|      .tag(9).button(BTN_POS(1,9), BTN_SIZE(1,1), | ||||
|         isPrintingFromMedia() ? | ||||
|           F("Printing") : | ||||
|       #if ENABLED(USB_FLASH_DRIVE_SUPPORT) | ||||
|         #ifdef LULZBOT_MANUAL_USB_STARTUP | ||||
|         (Sd2Card::ready() ? F("USB Drive") : F("Enable USB")) | ||||
|         #else | ||||
|         F("USB Drive") | ||||
|         #endif | ||||
|       #else | ||||
|         F("SD Card") | ||||
|       #endif | ||||
|       ); | ||||
|  | ||||
|   cmd.colors(!has_media ? action_btn : normal_btn).tag(10).button(BTN_POS(2,9), BTN_SIZE(1,1), F("Menu")); | ||||
| } | ||||
|  | ||||
| void StatusScreen::onStartup() { | ||||
|   // Load the bitmaps for the status screen | ||||
|   constexpr uint32_t base = ftdi_memory_map::RAM_G; | ||||
|   CLCD::mem_write_pgm(base + Bed_Heat_Icon_Info.RAMG_offset, Bed_Heat_Icon, sizeof(Bed_Heat_Icon)); | ||||
| } | ||||
|  | ||||
| void StatusScreen::onRedraw(draw_mode_t what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)); | ||||
|     cmd.cmd(CLEAR(true,true,true)); | ||||
|   } | ||||
|  | ||||
|   draw_syringe(what); | ||||
|   draw_temperature(what); | ||||
|   draw_arrows(what); | ||||
|   draw_overlay_icons(what); | ||||
|   draw_buttons(what); | ||||
|   draw_fine_motion(what); | ||||
| } | ||||
|  | ||||
| bool StatusScreen::onTouchStart(uint8_t) { | ||||
|   increment = fine_motion ? 0.25 : 1; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool StatusScreen::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: | ||||
|     case 2: | ||||
|     case 3: | ||||
|     case 4: | ||||
|     case 12: | ||||
|       if (!jog_xy) { | ||||
|         jog_xy = true; | ||||
|         injectCommands_P(PSTR("M17")); | ||||
|       } | ||||
|       break; | ||||
|     case 9: | ||||
|       #if ENABLED(USB_FLASH_DRIVE_SUPPORT) && defined(LULZBOT_MANUAL_USB_STARTUP) | ||||
|       if (!Sd2Card::ready()) { | ||||
|         StatusScreen::setStatusMessage(F("Insert USB drive...")); | ||||
|         Sd2Card::usbStartup(); | ||||
|       } else { | ||||
|         GOTO_SCREEN(FilesScreen); | ||||
|       } | ||||
|       #else | ||||
|         GOTO_SCREEN(FilesScreen); | ||||
|       #endif | ||||
|       break; | ||||
|     case 10: GOTO_SCREEN(MainMenu); break; | ||||
|     case 13: SpinnerDialogBox::enqueueAndWait_P(F("G112"));  break; | ||||
|     case 14: SpinnerDialogBox::enqueueAndWait_P(F("G28 Z")); break; | ||||
|     case 15: GOTO_SCREEN(TemperatureScreen);  break; | ||||
|     case 16: fine_motion = !fine_motion; break; | ||||
|     default: return false; | ||||
|   } | ||||
|   // If a passcode is enabled, the LockScreen will prevent the | ||||
|   // user from proceeding. | ||||
|   LockScreen::check_passcode(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool StatusScreen::onTouchHeld(uint8_t tag) { | ||||
|   if (tag >= 1 && tag <= 4 && !jog_xy) return false; | ||||
|   if (ExtUI::isMoving()) return false; // Don't allow moves to accumulate | ||||
|   #define UI_INCREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_INCREMENT(AxisPosition_mm, axis); | ||||
|   #define UI_DECREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_DECREMENT(AxisPosition_mm, axis); | ||||
|   switch (tag) { | ||||
|     case 1: UI_DECREMENT_AXIS(X);  break; | ||||
|     case 2: UI_INCREMENT_AXIS(X);  break; | ||||
|     case 4: UI_DECREMENT_AXIS(Y);  break; // NOTE: Y directions inverted because bed rather than needle moves | ||||
|     case 3: UI_INCREMENT_AXIS(Y);  break; | ||||
|     case 5: UI_DECREMENT_AXIS(Z);  break; | ||||
|     case 6: UI_INCREMENT_AXIS(Z);  break; | ||||
|     case 7: UI_DECREMENT_AXIS(E0); break; | ||||
|     case 8: UI_INCREMENT_AXIS(E0); break; | ||||
|     default: return false; | ||||
|   } | ||||
|   #undef UI_DECREMENT_AXIS | ||||
|   #undef UI_INCREMENT_AXIS | ||||
|   if (increment < 10 && !fine_motion) | ||||
|     increment += 0.5; | ||||
|   current_screen.onRefresh(); | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| void StatusScreen::setStatusMessage(progmem_str pstr) { | ||||
|   BioPrintingDialogBox::setStatusMessage(pstr); | ||||
| } | ||||
|  | ||||
| void StatusScreen::setStatusMessage(const char * const str) { | ||||
|   BioPrintingDialogBox::setStatusMessage(str); | ||||
| } | ||||
|  | ||||
| void StatusScreen::onIdle() { | ||||
|   if (isPrintingFromMedia()) | ||||
|     BioPrintingDialogBox::show(); | ||||
|  | ||||
|   if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) { | ||||
|     onRefresh(); | ||||
|     refresh_timer.start(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,87 @@ | ||||
| /********************* | ||||
|  * bio_tune_menu.cpp * | ||||
|  *********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
| using namespace ExtUI; | ||||
|  | ||||
| void TuneMenu::onRedraw(draw_mode_t what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)) | ||||
|        .font(font_medium); | ||||
|   } | ||||
|  | ||||
|   #define GRID_ROWS 8 | ||||
|   #define GRID_COLS 2 | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .font(font_large).text  ( BTN_POS(1,1), BTN_SIZE(2,1), F("Print Menu")) | ||||
|        .colors(normal_btn) | ||||
|        .font(font_medium) | ||||
|        .enabled(!isPrinting()).tag(2).button( BTN_POS(1,2), BTN_SIZE(2,1), isPrinting() ? F("Printing...") : F("Print Again")) | ||||
|        .enabled( isPrinting()).tag(3).button( BTN_POS(1,3), BTN_SIZE(2,1), F("Print Speed")) | ||||
|                               .tag(4).button( BTN_POS(1,4), BTN_SIZE(2,1), F("Bed Temperature")) | ||||
|         #if ENABLED(BABYSTEPPING) | ||||
|           .enabled(true) | ||||
|         #else | ||||
|           .enabled(false) | ||||
|         #endif | ||||
|                               .tag(5).button( BTN_POS(1,5), BTN_SIZE(2,1), F("Nudge Nozzle")) | ||||
|        .enabled(!isPrinting()).tag(6).button( BTN_POS(1,6), BTN_SIZE(2,1), F("Load Syringe")) | ||||
|        .enabled(!isPrinting()).tag(7).button( BTN_POS(1,7), BTN_SIZE(2,1), F("Unlock XY Axis")) | ||||
|        .colors(action_btn)    .tag(1).button( BTN_POS(1,8), BTN_SIZE(2,1), F("Back")); | ||||
|   } | ||||
|   #undef GRID_COLS | ||||
|   #undef GRID_ROWS | ||||
| } | ||||
|  | ||||
| bool TuneMenu::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1:  GOTO_PREVIOUS();                    break; | ||||
|     case 2: { | ||||
|       FileList files; | ||||
|       printFile(files.shortFilename()); | ||||
|       GOTO_PREVIOUS(); | ||||
|       break; | ||||
|     } | ||||
|     case 3: GOTO_SCREEN(FeedratePercentScreen); break; | ||||
|     case 4: GOTO_SCREEN(TemperatureScreen);     break; | ||||
|     case 5: GOTO_SCREEN(NudgeNozzleScreen);     break; | ||||
|     case 6: GOTO_SCREEN(BioConfirmHomeXYZ);     break; | ||||
|     case 7: StatusScreen::unlockMotors();       break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
							
								
								
									
										113
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/screens/boot_screen.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/screens/boot_screen.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| /******************* | ||||
|  * boot_screen.cpp * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| #include "../ftdi_eve_lib/extras/poly_ui.h" | ||||
| #include "../archim2-flash/flash_storage.h" | ||||
|  | ||||
| #ifdef TOUCH_UI_PORTRAIT | ||||
|   #include "../theme/bootscreen_logo_portrait.h" | ||||
| #else | ||||
|   #include "../theme/bootscreen_logo_landscape.h" | ||||
| #endif | ||||
|  | ||||
| using namespace FTDI; | ||||
|  | ||||
| void BootScreen::onRedraw(draw_mode_t) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(CLEAR_COLOR_RGB(0x000000)); | ||||
|   cmd.cmd(CLEAR(true,true,true)); | ||||
|  | ||||
|   CLCD::turn_on_backlight(); | ||||
|   SoundPlayer::set_volume(255); | ||||
| } | ||||
|  | ||||
| void BootScreen::onIdle() { | ||||
|   if (CLCD::is_touching()) { | ||||
|     // If the user is touching the screen at startup, then | ||||
|     // assume the user wants to re-calibrate the screen. | ||||
|     // This gives the user the ability to recover a | ||||
|     // miscalibration that has been stored to EEPROM. | ||||
|  | ||||
|     // Also reset display parameters to defaults, just | ||||
|     // in case the display is borked. | ||||
|     InterfaceSettingsScreen::failSafeSettings(); | ||||
|  | ||||
|     GOTO_SCREEN(TouchCalibrationScreen); | ||||
|     current_screen.forget(); | ||||
|     PUSH_SCREEN(StatusScreen); | ||||
|   } else { | ||||
|     if (!UIFlashStorage::is_valid()) { | ||||
|       SpinnerDialogBox::show(F("Please wait...")); | ||||
|       UIFlashStorage::format_flash(); | ||||
|       SpinnerDialogBox::hide(); | ||||
|     } | ||||
|  | ||||
|     if (UIData::animations_enabled()) { | ||||
|       // If there is a startup video in the flash SPI, play | ||||
|       // that, otherwise show a static splash screen. | ||||
|       if (!MediaPlayerScreen::playBootMedia()) | ||||
|         showSplashScreen(); | ||||
|     } | ||||
|     #ifdef LULZBOT_USE_BIOPRINTER_UI | ||||
|       GOTO_SCREEN(BioConfirmHomeXYZ); | ||||
|       current_screen.forget(); | ||||
|       PUSH_SCREEN(StatusScreen); | ||||
|       PUSH_SCREEN(BioConfirmHomeE); | ||||
|     #else | ||||
|       GOTO_SCREEN(StatusScreen); | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| void BootScreen::showSplashScreen() { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(CMD_DLSTART); | ||||
|   cmd.cmd(CLEAR_COLOR_RGB(0xDEEA5C)); | ||||
|   cmd.cmd(CLEAR(true,true,true)); | ||||
|  | ||||
|   #define POLY(A) PolyUI::poly_reader_t(A, sizeof(A)/sizeof(A[0])) | ||||
|  | ||||
|   PolyUI ui(cmd); | ||||
|  | ||||
|   cmd.cmd(COLOR_RGB(0xC1D82F)); | ||||
|   ui.fill(POLY(logo_green)); | ||||
|   cmd.cmd(COLOR_RGB(0x000000)); | ||||
|   ui.fill(POLY(logo_black)); | ||||
|   ui.fill(POLY(logo_type)); | ||||
|   ui.fill(POLY(logo_mark)); | ||||
|   cmd.cmd(COLOR_RGB(0xFFFFFF)); | ||||
|   ui.fill(POLY(logo_white)); | ||||
|  | ||||
|   cmd.cmd(DL::DL_DISPLAY); | ||||
|   cmd.cmd(CMD_SWAP); | ||||
|   cmd.execute(); | ||||
|  | ||||
|   ExtUI::delay_ms(2500); | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,323 @@ | ||||
| /****************************** | ||||
|  * change_filament_screen.cpp * | ||||
|  ******************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| using namespace ExtUI; | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| #define COOL_TEMP  40 | ||||
| #define LOW_TEMP  180 | ||||
| #define MED_TEMP  200 | ||||
| #define HIGH_TEMP 220 | ||||
|  | ||||
| /****************** COLOR SCALE ***********************/ | ||||
|  | ||||
| uint32_t getWarmColor(uint16_t temp, uint16_t cool, uint16_t low, uint16_t med, uint16_t high) { | ||||
|   rgb_t R0, R1, mix; | ||||
|  | ||||
|   float t; | ||||
|   if (temp < cool) { | ||||
|     R0 = cool_rgb; | ||||
|     R1 = low_rgb; | ||||
|     t  = 0; | ||||
|   } | ||||
|   else if (temp < low) { | ||||
|     R0 = cool_rgb; | ||||
|     R1 = low_rgb; | ||||
|     t = (float(temp)-cool)/(low-cool); | ||||
|   } | ||||
|   else if (temp < med) { | ||||
|     R0 = low_rgb; | ||||
|     R1 = med_rgb; | ||||
|     t = (float(temp)-low)/(med-low); | ||||
|   } | ||||
|   else if (temp < high) { | ||||
|     R0 = med_rgb; | ||||
|     R1 = high_rgb; | ||||
|     t = (float(temp)-med)/(high-med); | ||||
|   } | ||||
|   else if (temp >= high) { | ||||
|     R0 = med_rgb; | ||||
|     R1 = high_rgb; | ||||
|     t = 1; | ||||
|   } | ||||
|   rgb_t::lerp(t, R0, R1, mix); | ||||
|   return mix; | ||||
| } | ||||
|  | ||||
| void ChangeFilamentScreen::drawTempGradient(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(SCISSOR_XY   (x, y)) | ||||
|      .cmd(SCISSOR_SIZE (w, h/2)) | ||||
|      .gradient         (x, y,     high_rgb, x, y+h/2, med_rgb) | ||||
|      .cmd(SCISSOR_XY   (x, y+h/2)) | ||||
|      .cmd(SCISSOR_SIZE (w, h/2)) | ||||
|      .gradient         (x, y+h/2, med_rgb,  x, y+h, low_rgb) | ||||
|      .cmd(SCISSOR_XY   ()) | ||||
|      .cmd(SCISSOR_SIZE ()); | ||||
| } | ||||
|  | ||||
| void ChangeFilamentScreen::onEntry() { | ||||
|   screen_data.ChangeFilamentScreen.e_tag = ExtUI::getActiveTool() + 10; | ||||
|   screen_data.ChangeFilamentScreen.t_tag = 0; | ||||
|   screen_data.ChangeFilamentScreen.repeat_tag = 0; | ||||
|   screen_data.ChangeFilamentScreen.saved_extruder = getActiveTool(); | ||||
| } | ||||
|  | ||||
| void ChangeFilamentScreen::onExit() { | ||||
|   setActiveTool(screen_data.ChangeFilamentScreen.saved_extruder, true); | ||||
| } | ||||
|  | ||||
| void ChangeFilamentScreen::onRedraw(draw_mode_t what) { | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   #ifdef TOUCH_UI_PORTRAIT | ||||
|     #define GRID_COLS 2 | ||||
|     #define GRID_ROWS 11 | ||||
|   #else | ||||
|     #define GRID_COLS 4 | ||||
|     #define GRID_ROWS 6 | ||||
|   #endif | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)) | ||||
|        .tag(0) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .font(font_large) | ||||
|     #else | ||||
|        .font(font_medium) | ||||
|     #endif | ||||
|        .text(BTN_POS(1,1), BTN_SIZE(2,1), F("Extruder Selection:")) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .text(BTN_POS(1,7), BTN_SIZE(1,1), F("Current Temp:")) | ||||
|     #else | ||||
|        .text(BTN_POS(3,1), BTN_SIZE(2,1), F("Current Temp:")) | ||||
|        .font(font_small) | ||||
|     #endif | ||||
|        .text(BTN_POS(1,3), BTN_SIZE(2,1), F("Removal Temp:")); | ||||
|     drawTempGradient(BTN_POS(1,4), BTN_SIZE(1,3)); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     char e_str[15]; | ||||
|  | ||||
|     const char *idle = PSTR("%-3d C / idle"); | ||||
|     const char *not_idle = PSTR("%-3d / %-3d C"); | ||||
|  | ||||
|     sprintf_P( | ||||
|       e_str, | ||||
|       isHeaterIdle(getExtruder()) ? idle : not_idle, | ||||
|       ROUND(getActualTemp_celsius(getExtruder())), | ||||
|       ROUND(getTargetTemp_celsius(getExtruder())) | ||||
|     ); | ||||
|  | ||||
|     const rgb_t tcol = getWarmColor(getActualTemp_celsius(getExtruder()), COOL_TEMP, LOW_TEMP, MED_TEMP, HIGH_TEMP); | ||||
|     cmd.cmd(COLOR_RGB(tcol)) | ||||
|        .tag(15) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .rectangle(BTN_POS(2,7), BTN_SIZE(1,1)) | ||||
|     #else | ||||
|        .rectangle(BTN_POS(3,2), BTN_SIZE(2,1)) | ||||
|     #endif | ||||
|        .cmd(COLOR_RGB(tcol.luminance() > 128 ? 0x000000 : 0xFFFFFF)) | ||||
|        .font(font_medium) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .text(BTN_POS(2,7), BTN_SIZE(1,1), e_str) | ||||
|     #else | ||||
|        .text(BTN_POS(3,2), BTN_SIZE(2,1), e_str) | ||||
|     #endif | ||||
|        .colors(normal_btn); | ||||
|  | ||||
|     const bool t_ok = getActualTemp_celsius(getExtruder()) > getSoftenTemp() - 10; | ||||
|  | ||||
|     if (screen_data.ChangeFilamentScreen.t_tag && !t_ok) { | ||||
|       cmd.text(BTN_POS(1,6), BTN_SIZE(1,1), F("Heating...")); | ||||
|     } else if (getActualTemp_celsius(getExtruder()) > 100) { | ||||
|       cmd.cmd(COLOR_RGB(0xFF0000)) | ||||
|          .text(BTN_POS(1,4), BTN_SIZE(1,1), F("Caution:")) | ||||
|          .colors(normal_btn) | ||||
|          .text(BTN_POS(1,6), BTN_SIZE(1,1), F("Hot!")); | ||||
|     } | ||||
|  | ||||
|     #define TOG_STYLE(A) colors(A ? action_btn : normal_btn) | ||||
|  | ||||
|     const bool tog2  = screen_data.ChangeFilamentScreen.t_tag == 2; | ||||
|     const bool tog3  = screen_data.ChangeFilamentScreen.t_tag == 3; | ||||
|     const bool tog4  = screen_data.ChangeFilamentScreen.t_tag == 4; | ||||
|     const bool tog10 = screen_data.ChangeFilamentScreen.e_tag == 10; | ||||
|     #if HOTENDS > 1 | ||||
|     const bool tog11 = screen_data.ChangeFilamentScreen.e_tag == 11; | ||||
|     #endif | ||||
|  | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       cmd.font(font_large) | ||||
|     #else | ||||
|       cmd.font(font_medium) | ||||
|     #endif | ||||
|        .TOG_STYLE(tog10) | ||||
|        .tag(10)          .button (BTN_POS(1,2), BTN_SIZE(1,1), F("1")) | ||||
|     #if HOTENDS < 2 | ||||
|        .enabled(false) | ||||
|     #else | ||||
|        .TOG_STYLE(tog11) | ||||
|     #endif | ||||
|        .tag(11)          .button (BTN_POS(2,2), BTN_SIZE(1,1), F("2")); | ||||
|  | ||||
|     if (!t_ok) reset_menu_timeout(); | ||||
|  | ||||
|     const bool tog7 = screen_data.ChangeFilamentScreen.repeat_tag == 7; | ||||
|     const bool tog8 = screen_data.ChangeFilamentScreen.repeat_tag == 8; | ||||
|  | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       cmd.font(font_large) | ||||
|     #else | ||||
|       cmd.font(font_small) | ||||
|     #endif | ||||
|        .tag(2) .TOG_STYLE(tog2) .button (BTN_POS(2,6), BTN_SIZE(1,1), F( STRINGIFY(LOW_TEMP)  "C (PLA)")) | ||||
|        .tag(3) .TOG_STYLE(tog3) .button (BTN_POS(2,5), BTN_SIZE(1,1), F( STRINGIFY(MED_TEMP)  "C (ABS)")) | ||||
|        .tag(4) .TOG_STYLE(tog4) .button (BTN_POS(2,4), BTN_SIZE(1,1), F( STRINGIFY(HIGH_TEMP) "C (High)")) | ||||
|        .colors(normal_btn) | ||||
|  | ||||
|     // Add tags to color gradient | ||||
|     .cmd(COLOR_MASK(0,0,0,0)) | ||||
|     .tag(2) .rectangle(BTN_POS(1,6), BTN_SIZE(1,1)) | ||||
|     .tag(3) .rectangle(BTN_POS(1,5), BTN_SIZE(1,1)) | ||||
|     .tag(4) .rectangle(BTN_POS(1,4), BTN_SIZE(1,1)) | ||||
|     .cmd(COLOR_MASK(1,1,1,1)) | ||||
|  | ||||
|     .cmd(COLOR_RGB(t_ok ? bg_text_enabled : bg_text_disabled)) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .font(font_large) | ||||
|        .tag(0)                              .text   (BTN_POS(1,8),  BTN_SIZE(1,1), F("Unload")) | ||||
|                                             .text   (BTN_POS(2,8),  BTN_SIZE(1,1), F("Load/Extrude")) | ||||
|        .tag(5)                .enabled(t_ok).button (BTN_POS(1,9),  BTN_SIZE(1,1), F("Momentary")) | ||||
|        .tag(6)                .enabled(t_ok).button (BTN_POS(2,9),  BTN_SIZE(1,1), F("Momentary")) | ||||
|        .tag(7).TOG_STYLE(tog7).enabled(t_ok).button (BTN_POS(1,10), BTN_SIZE(1,1), F("Continuous")) | ||||
|        .tag(8).TOG_STYLE(tog8).enabled(t_ok).button (BTN_POS(2,10), BTN_SIZE(1,1), F("Continuous")) | ||||
|        .tag(1).colors(action_btn)           .button (BTN_POS(1,11), BTN_SIZE(2,1), F("Back")); | ||||
|     #else | ||||
|        .font(font_small) | ||||
|        .tag(0)                              .text   (BTN_POS(3,3),  BTN_SIZE(1,1), F("Unload")) | ||||
|                                             .text   (BTN_POS(4,3),  BTN_SIZE(1,1), F("Load/Extrude")) | ||||
|        .tag(5)                .enabled(t_ok).button (BTN_POS(3,4),  BTN_SIZE(1,1), F("Momentary")) | ||||
|        .tag(6)                .enabled(t_ok).button (BTN_POS(4,4),  BTN_SIZE(1,1), F("Momentary")) | ||||
|        .tag(7).TOG_STYLE(tog7).enabled(t_ok).button (BTN_POS(3,5),  BTN_SIZE(1,1), F("Continuous")) | ||||
|        .tag(8).TOG_STYLE(tog8).enabled(t_ok).button (BTN_POS(4,5),  BTN_SIZE(1,1), F("Continuous")) | ||||
|        .font(font_medium) | ||||
|        .tag(1).colors(action_btn)           .button (BTN_POS(3,6),  BTN_SIZE(2,1), F("Back")); | ||||
|     #endif | ||||
|   } | ||||
|   #undef GRID_COLS | ||||
|   #undef GRID_ROWS | ||||
| } | ||||
|  | ||||
| uint8_t ChangeFilamentScreen::getSoftenTemp() { | ||||
|   switch (screen_data.ChangeFilamentScreen.t_tag) { | ||||
|     case 2:  return LOW_TEMP; | ||||
|     case 3:  return MED_TEMP; | ||||
|     case 4:  return HIGH_TEMP; | ||||
|     default: return EXTRUDE_MINTEMP; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ExtUI::extruder_t ChangeFilamentScreen::getExtruder() { | ||||
|   switch (screen_data.ChangeFilamentScreen.e_tag) { | ||||
|     case 13: return ExtUI::E3; | ||||
|     case 12: return ExtUI::E2; | ||||
|     case 11: return ExtUI::E1; | ||||
|     default: return ExtUI::E0; | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool ChangeFilamentScreen::onTouchStart(uint8_t tag) { | ||||
|   // Make the Momentary and Continuous buttons slightly more responsive | ||||
|   switch (tag) { | ||||
|     case 5: case 6: case 7: case 8: | ||||
|       return ChangeFilamentScreen::onTouchHeld(tag); | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool ChangeFilamentScreen::onTouchEnd(uint8_t tag) { | ||||
|   using namespace ExtUI; | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS(); break; | ||||
|     case 2: | ||||
|     case 3: | ||||
|     case 4: | ||||
|       // Change temperature | ||||
|       screen_data.ChangeFilamentScreen.t_tag = tag; | ||||
|       setTargetTemp_celsius(getSoftenTemp(), getExtruder()); | ||||
|       break; | ||||
|     case 7: | ||||
|       screen_data.ChangeFilamentScreen.repeat_tag = (screen_data.ChangeFilamentScreen.repeat_tag == 7) ? 0 : 7; | ||||
|       break; | ||||
|     case 8: | ||||
|       screen_data.ChangeFilamentScreen.repeat_tag = (screen_data.ChangeFilamentScreen.repeat_tag == 8) ? 0 : 8; | ||||
|       break; | ||||
|     case 10: | ||||
|     case 11: | ||||
|       // Change extruder | ||||
|       screen_data.ChangeFilamentScreen.e_tag      = tag; | ||||
|       screen_data.ChangeFilamentScreen.t_tag      = 0; | ||||
|       screen_data.ChangeFilamentScreen.repeat_tag = 0; | ||||
|       setActiveTool(getExtruder(), true); | ||||
|       break; | ||||
|     case 15: GOTO_SCREEN(TemperatureScreen); break; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool ChangeFilamentScreen::onTouchHeld(uint8_t tag) { | ||||
|   if (ExtUI::isMoving()) return false; // Don't allow moves to accumulate | ||||
|   constexpr float increment = 1; | ||||
|   #define UI_INCREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_INCREMENT(AxisPosition_mm, axis); | ||||
|   #define UI_DECREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_DECREMENT(AxisPosition_mm, axis); | ||||
|   switch (tag) { | ||||
|     case 5: case 7: UI_DECREMENT_AXIS(getExtruder()); break; | ||||
|     case 6: case 8: UI_INCREMENT_AXIS(getExtruder()); break; | ||||
|     default: return false; | ||||
|   } | ||||
|   #undef UI_DECREMENT_AXIS | ||||
|   #undef UI_INCREMENT_AXIS | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| void ChangeFilamentScreen::onIdle() { | ||||
|   if (screen_data.ChangeFilamentScreen.repeat_tag) onTouchHeld(screen_data.ChangeFilamentScreen.repeat_tag); | ||||
|   if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) { | ||||
|     onRefresh(); | ||||
|     refresh_timer.start(); | ||||
|   } | ||||
|   BaseScreen::onIdle(); | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,47 @@ | ||||
| /************************************** | ||||
|  * confirm_abort_print_dialog_box.cpp * | ||||
|  **************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace ExtUI; | ||||
|  | ||||
| void ConfirmAbortPrintDialogBox::onRedraw(draw_mode_t) { | ||||
|   drawMessage(F("Are you sure you want to cancel the print?")); | ||||
|   drawYesNoButtons(); | ||||
| } | ||||
|  | ||||
| bool ConfirmAbortPrintDialogBox::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: | ||||
|       GOTO_PREVIOUS(); | ||||
|       stopPrint(); | ||||
|       return true; | ||||
|     default: | ||||
|       return DialogBoxBaseClass::onTouchEnd(tag); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,48 @@ | ||||
| /******************************************* | ||||
|  * confirm_auto_calibration_dialog_box.cpp * | ||||
|  *******************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ENABLED(CALIBRATION_GCODE) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void ConfirmAutoCalibrationDialogBox::onRedraw(draw_mode_t) { | ||||
|   drawMessage(F("For best results, unload the filament and clean the hotend prior to starting calibration. Continue?")); | ||||
|   drawYesNoButtons(); | ||||
| } | ||||
|  | ||||
| bool ConfirmAutoCalibrationDialogBox::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: | ||||
|       GOTO_SCREEN(StatusScreen); | ||||
|       injectCommands_P(PSTR(LULZBOT_CALIBRATION_COMMANDS)); | ||||
|       return true; | ||||
|     default: | ||||
|       return DialogBoxBaseClass::onTouchEnd(tag); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,54 @@ | ||||
| /************************************** | ||||
|  * confirm_erase_flash_dialog_box.cpp * | ||||
|  **************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ENABLED(DEVELOPER_SCREENS) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| #include "../archim2-flash/flash_storage.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
|  | ||||
| void ConfirmEraseFlashDialogBox::onRedraw(draw_mode_t) { | ||||
|   drawMessage(F("Are you sure? SPI flash will be erased.")); | ||||
|   drawYesNoButtons(); | ||||
| } | ||||
|  | ||||
| bool ConfirmEraseFlashDialogBox::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: | ||||
|       SpinnerDialogBox::show(F("Erasing...")); | ||||
|       UIFlashStorage::format_flash(); | ||||
|       SpinnerDialogBox::hide(); | ||||
|       AlertDialogBox::show(F("SPI flash erased")); | ||||
|       // Remove ConfirmEraseFlashDialogBox from the stack | ||||
|       // so the alert box doesn't return to me. | ||||
|       current_screen.forget(); | ||||
|       return true; | ||||
|     default: | ||||
|       return DialogBoxBaseClass::onTouchEnd(tag); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,58 @@ | ||||
| /************************************** | ||||
|  * confirm_user_request_alert_box.cpp * | ||||
|  **************************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
|  | ||||
| void ConfirmUserRequestAlertBox::onRedraw(draw_mode_t mode) { | ||||
|   AlertDialogBox::onRedraw(mode); // Required for the GOTO_SCREEN function to work | ||||
| } | ||||
|  | ||||
| bool ConfirmUserRequestAlertBox::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: | ||||
|       ExtUI::setUserConfirmed(); | ||||
|       GOTO_PREVIOUS(); | ||||
|       return true; | ||||
|     case 2: GOTO_PREVIOUS(); return true; | ||||
|     default:                 return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void ConfirmUserRequestAlertBox::show(const char* msg) { | ||||
|   drawMessage(msg); | ||||
|   storeBackground(); | ||||
|   screen_data.AlertDialogBox.isError = false; | ||||
|   GOTO_SCREEN(ConfirmUserRequestAlertBox); | ||||
| } | ||||
|  | ||||
| void ConfirmUserRequestAlertBox::hide() { | ||||
|   if (AT_SCREEN(ConfirmUserRequestAlertBox)) | ||||
|     GOTO_PREVIOUS(); | ||||
| } | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,63 @@ | ||||
| /*********************************** | ||||
|  * default_acceleration_screen.cpp * | ||||
|  ***********************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void DefaultAccelerationScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.precision(0); | ||||
|   w.units(PSTR("mm/s^2")); | ||||
|   w.heading(      PSTR("Default Acceleration")); | ||||
|   w.color(other); | ||||
|   w.adjuster(  2, PSTR("Printing:"),   getPrintingAcceleration_mm_s2() ); | ||||
|   w.adjuster(  4, PSTR("Travel:"),     getTravelAcceleration_mm_s2() ); | ||||
|   w.adjuster(  6, PSTR("Retraction:"), getRetractAcceleration_mm_s2() ); | ||||
|   w.increments(); | ||||
|   w.button(    8, PSTR("Set Axis Maximum")); | ||||
| } | ||||
|  | ||||
| bool DefaultAccelerationScreen::onTouchHeld(uint8_t tag) { | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case  2: UI_DECREMENT(PrintingAcceleration_mm_s2); break; | ||||
|     case  3: UI_INCREMENT(PrintingAcceleration_mm_s2); break; | ||||
|     case  4: UI_DECREMENT(TravelAcceleration_mm_s2);   break; | ||||
|     case  5: UI_INCREMENT(TravelAcceleration_mm_s2);   break; | ||||
|     case  6: UI_DECREMENT(RetractAcceleration_mm_s2);  break; | ||||
|     case  7: UI_INCREMENT(RetractAcceleration_mm_s2);  break; | ||||
|     case  8: GOTO_SCREEN(MaxAccelerationScreen);       break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,150 @@ | ||||
| /********************** | ||||
|  * developer_menu.cpp * | ||||
|  **********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ENABLED(DEVELOPER_SCREENS) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| #include "../archim2-flash/flash_storage.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void DeveloperMenu::onRedraw(draw_mode_t what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)) | ||||
|        .font(font_medium) | ||||
|        .tag(0); | ||||
|  | ||||
|     #ifdef SPI_FLASH_SS | ||||
|       constexpr bool has_flash = true; | ||||
|     #else | ||||
|       constexpr bool has_flash = false; | ||||
|     #endif | ||||
|  | ||||
|     #if ENABLED(SDSUPPORT) | ||||
|       constexpr bool has_media = true; | ||||
|     #else | ||||
|       constexpr bool has_media = false; | ||||
|     #endif | ||||
|  | ||||
|     cmd.cmd(COLOR_RGB(bg_text_enabled)); | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       #define GRID_ROWS 10 | ||||
|       #define GRID_COLS 1 | ||||
|       cmd.font(font_large)         .text  ( BTN_POS(1,1), BTN_SIZE(1,1), F("Developer Menu")) | ||||
|          .colors(normal_btn) | ||||
|          .tag(2).font(font_medium) .button( BTN_POS(1,2), BTN_SIZE(1,1), F("Show All Widgets")) | ||||
|          .tag(3)                   .button( BTN_POS(1,3), BTN_SIZE(1,1), F("Stress Test")) | ||||
|          .tag(4)                   .button( BTN_POS(1,4), BTN_SIZE(1,1), F("Show Touch Registers")) | ||||
|          .tag(5)                   .button( BTN_POS(1,5), BTN_SIZE(1,1), F("Play Song")) | ||||
|          .tag(6).enabled(has_media).button( BTN_POS(1,6), BTN_SIZE(1,1), F("Play Video from Media")) | ||||
|          .tag(7).enabled(has_flash).button( BTN_POS(1,7), BTN_SIZE(1,1), F("Play Video from SPI Flash")) | ||||
|          .tag(8).enabled(has_flash).button( BTN_POS(1,8), BTN_SIZE(1,1), F("Load Video to SPI Flash")) | ||||
|          .tag(9).enabled(has_flash).button( BTN_POS(1,9), BTN_SIZE(1,1), F("Erase SPI Flash")) | ||||
|  | ||||
|          .tag(1).colors(action_btn) | ||||
|                                    .button( BTN_POS(1,10), BTN_SIZE(1,1), F("Back")); | ||||
|     #else | ||||
|       #define GRID_ROWS 6 | ||||
|       #define GRID_COLS 2 | ||||
|       cmd.font(font_medium)        .text  ( BTN_POS(1,1), BTN_SIZE(2,1), F("Developer Menu")) | ||||
|          .colors(normal_btn) | ||||
|          .tag(2).font(font_small)  .button( BTN_POS(1,2), BTN_SIZE(1,1), F("Show All Widgets")) | ||||
|          .tag(3)                   .button( BTN_POS(1,3), BTN_SIZE(1,1), F("Show Touch Registers")) | ||||
|          .tag(9)                   .button( BTN_POS(1,4), BTN_SIZE(1,1), F("Show Pin States")) | ||||
|          .tag(4)                   .button( BTN_POS(1,5), BTN_SIZE(1,1), F("Play Song")) | ||||
|          .tag(5).enabled(has_media).button( BTN_POS(2,2), BTN_SIZE(1,1), F("Play Video from Media")) | ||||
|          .tag(6).enabled(has_flash).button( BTN_POS(2,3), BTN_SIZE(1,1), F("Play Video from SPI Flash")) | ||||
|          .tag(7).enabled(has_flash).button( BTN_POS(2,4), BTN_SIZE(1,1), F("Load Video to SPI Flash")) | ||||
|          .tag(8).enabled(has_flash).button( BTN_POS(2,5), BTN_SIZE(1,1), F("Erase SPI Flash")) | ||||
|          .tag(1).colors(action_btn) | ||||
|                                    .button( BTN_POS(1,6), BTN_SIZE(2,1), F("Back")); | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool DeveloperMenu::onTouchEnd(uint8_t tag) { | ||||
|   using namespace Theme; | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS();                            break; | ||||
|     case 2: GOTO_SCREEN(WidgetsScreen);                 break; | ||||
|     case 3: | ||||
|       PUSH_SCREEN(StressTestScreen); | ||||
|       AlertDialogBox::show(F("Please do not run this test unattended as it may cause your printer to malfunction.")); | ||||
|       current_screen.forget(); | ||||
|       break; | ||||
|     case 4: GOTO_SCREEN(TouchRegistersScreen);          break; | ||||
|     case 5: sound.play(js_bach_joy, PLAY_ASYNCHRONOUS); break; | ||||
|     #if ENABLED(SDSUPPORT) | ||||
|     case 6: | ||||
|         if (!MediaPlayerScreen::playCardMedia()) | ||||
|           AlertDialogBox::showError(F("Cannot open STARTUP.AVI")); | ||||
|         break; | ||||
|     #endif | ||||
|     #ifdef SPI_FLASH_SS | ||||
|       case 7: | ||||
|         if (!MediaPlayerScreen::playBootMedia()) | ||||
|           AlertDialogBox::showError(F("No boot media available")); | ||||
|         break; | ||||
|       case 8: | ||||
|       { | ||||
|         SpinnerDialogBox::show(F("Saving...")); | ||||
|         UIFlashStorage::error_t res = UIFlashStorage::write_media_file(F("STARTUP.AVI")); | ||||
|         SpinnerDialogBox::hide(); | ||||
|         reset_menu_timeout(); | ||||
|         switch (res) { | ||||
|           case UIFlashStorage::SUCCESS: | ||||
|             AlertDialogBox::show(F("File copied!")); | ||||
|             break; | ||||
|  | ||||
|           case UIFlashStorage::READ_ERROR: | ||||
|             AlertDialogBox::showError(F("Failed to read file")); | ||||
|             break; | ||||
|  | ||||
|           case UIFlashStorage::VERIFY_ERROR: | ||||
|             AlertDialogBox::showError(F("Failed to verify file")); | ||||
|             break; | ||||
|  | ||||
|           case UIFlashStorage::FILE_NOT_FOUND: | ||||
|             AlertDialogBox::showError(F("Cannot open STARTUP.AVI")); | ||||
|             break; | ||||
|  | ||||
|           case UIFlashStorage::WOULD_OVERWRITE: | ||||
|             AlertDialogBox::showError(F("Cannot overwrite existing media.")); | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case 9: GOTO_SCREEN(ConfirmEraseFlashDialogBox); break; | ||||
|     #endif | ||||
|     case 10: GOTO_SCREEN(EndstopStatesScreen); break; | ||||
|     default: return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,83 @@ | ||||
| /***************************** | ||||
|  * dialog_box_base_class.cpp * | ||||
|  *****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| #define GRID_COLS 2 | ||||
| #define GRID_ROWS 8 | ||||
|  | ||||
| template<typename T> | ||||
| void DialogBoxBaseClass::drawMessage(const T message, int16_t font) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(CMD_DLSTART) | ||||
|      .cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|      .cmd(CLEAR(true,true,true)) | ||||
|      .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|      .tag(0); | ||||
|   draw_text_box(cmd, BTN_POS(1,1), BTN_SIZE(2,3), message, OPT_CENTER, font ? font : font_large); | ||||
|   cmd.colors(normal_btn); | ||||
| } | ||||
|  | ||||
| template void DialogBoxBaseClass::drawMessage(const char *, int16_t font); | ||||
| template void DialogBoxBaseClass::drawMessage(const progmem_str, int16_t font); | ||||
|  | ||||
| void DialogBoxBaseClass::drawYesNoButtons(uint8_t default_btn) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.font(font_medium) | ||||
|      .colors(default_btn == 1 ? action_btn : normal_btn).tag(1).button( BTN_POS(1,8), BTN_SIZE(1,1), F("Yes")) | ||||
|      .colors(default_btn == 2 ? action_btn : normal_btn).tag(2).button( BTN_POS(2,8), BTN_SIZE(1,1), F("No")); | ||||
| } | ||||
|  | ||||
| void DialogBoxBaseClass::drawOkayButton() { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.font(font_medium) | ||||
|      .tag(1).button( BTN_POS(1,8), BTN_SIZE(2,1), F("Okay")); | ||||
| } | ||||
|  | ||||
| void DialogBoxBaseClass::drawButton(const progmem_str label) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.font(font_medium) | ||||
|      .tag(1).button( BTN_POS(1,8), BTN_SIZE(2,1), label); | ||||
| } | ||||
|  | ||||
| void DialogBoxBaseClass::drawSpinner() { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(COLOR_RGB(bg_text_enabled)) | ||||
|      .spinner(BTN_POS(1,4), BTN_SIZE(2,3)).execute(); | ||||
| } | ||||
|  | ||||
| bool DialogBoxBaseClass::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS(); return true; | ||||
|     case 2: GOTO_PREVIOUS(); return true; | ||||
|     default:                 return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,61 @@ | ||||
| /***************************** | ||||
|  * display_tuning_screen.cpp * | ||||
|  *****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void DisplayTuningScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.precision(0, BaseNumericAdjustmentScreen::DEFAULT_LOWEST); | ||||
|   w.units(PSTR("")); | ||||
|   w.heading(     PSTR("Display Tuning")); | ||||
|   w.color(other); | ||||
|   w.adjuster( 2, PSTR("H Offset:"), CLCD::mem_read_16(CLCD::REG::HOFFSET) ); | ||||
|   w.adjuster( 4, PSTR("V Offset:"), CLCD::mem_read_16(CLCD::REG::VOFFSET) ); | ||||
|   w.increments(); | ||||
|   w.heading(     PSTR("Touch Screen")); | ||||
|   w.button(6, PSTR("Calibrate")); | ||||
| } | ||||
|  | ||||
| bool DisplayTuningScreen::onTouchHeld(uint8_t tag) { | ||||
|   #define REG_INCREMENT(a,i) CLCD::mem_write_16(CLCD::REG::a, CLCD::mem_read_16(CLCD::REG::a) + i) | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case  2: REG_INCREMENT(HOFFSET, -increment);  break; | ||||
|     case  3: REG_INCREMENT(HOFFSET,  increment);  break; | ||||
|     case  4: REG_INCREMENT(VOFFSET, -increment);  break; | ||||
|     case  5: REG_INCREMENT(VOFFSET,  increment);  break; | ||||
|     case  6: GOTO_SCREEN(TouchCalibrationScreen); break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,155 @@ | ||||
| /**************************** | ||||
|  * endstop_state_screen.cpp * | ||||
|  ****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
| using namespace ExtUI; | ||||
|  | ||||
| void EndstopStatesScreen::onEntry() { | ||||
|   BaseScreen::onEntry(); | ||||
|   #ifdef LULZBOT_SET_PROBE_PINS_STATE | ||||
|     LULZBOT_SET_PROBE_PINS_STATE(true) | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void EndstopStatesScreen::onExit() { | ||||
|   BaseScreen::onExit(); | ||||
|   #ifdef LULZBOT_SET_PROBE_PINS_STATE | ||||
|     LULZBOT_SET_PROBE_PINS_STATE(false) | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void EndstopStatesScreen::onRedraw(draw_mode_t) { | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|      .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|      .cmd(CLEAR(true,true,true)) | ||||
|      .tag(0); | ||||
|  | ||||
|   #define GRID_ROWS 7 | ||||
|   #define GRID_COLS 6 | ||||
|  | ||||
|   #define PIN_BTN(X,Y,PIN,LABEL)          button(BTN_POS(X,Y), BTN_SIZE(2,1), F(LABEL)) | ||||
|   #define PIN_ENABLED(LABEL,PIN,INV,X,Y)  cmd.enabled(1).colors(READ(PIN##_PIN) != INV ? action_btn : normal_btn).PIN_BTN(X,Y,PIN,LABEL); | ||||
|   #define PIN_DISABLED(LABEL,PIN,INV,X,Y) cmd.enabled(0).PIN_BTN(X,Y,PIN,LABEL); | ||||
|  | ||||
|   #ifdef TOUCH_UI_PORTRAIT | ||||
|   cmd.font(font_large) | ||||
|   #else | ||||
|   cmd.font(font_medium) | ||||
|   #endif | ||||
|      .text(BTN_POS(1,1), BTN_SIZE(6,1), F("Endstop States:")) | ||||
|      .font(font_tiny); | ||||
|   #if PIN_EXISTS(X_MAX) | ||||
|     PIN_ENABLED ("X Max", X_MAX,X_MAX_ENDSTOP_INVERTING,1,2) | ||||
|   #else | ||||
|     PIN_DISABLED("X Max",X_MAX,X_MAX_ENDSTOP_INVERTING,1,2) | ||||
|   #endif | ||||
|   #if PIN_EXISTS(Y_MAX) | ||||
|     PIN_ENABLED ("Y Max",Y_MAX,Y_MAX_ENDSTOP_INVERTING,3,2) | ||||
|   #else | ||||
|     PIN_DISABLED("Y Max",Y_MAX,Y_MAX_ENDSTOP_INVERTING,3,2) | ||||
|   #endif | ||||
|   #if PIN_EXISTS(Z_MAX) | ||||
|     PIN_ENABLED ("Z Max",Z_MAX,Z_MAX_ENDSTOP_INVERTING,5,2) | ||||
|   #else | ||||
|     PIN_DISABLED("Z Max",Z_MAX,Z_MAX_ENDSTOP_INVERTING,5,2) | ||||
|   #endif | ||||
|   #if PIN_EXISTS(X_MIN) | ||||
|     PIN_ENABLED ("X Min",X_MIN,X_MIN_ENDSTOP_INVERTING,1,3) | ||||
|   #else | ||||
|     PIN_DISABLED("X Min",X_MIN,X_MIN_ENDSTOP_INVERTING,1,3) | ||||
|   #endif | ||||
|   #if PIN_EXISTS(Y_MIN) | ||||
|     PIN_ENABLED ("Y Min",Y_MIN,Y_MIN_ENDSTOP_INVERTING,3,3) | ||||
|   #else | ||||
|     PIN_DISABLED("Y Min",Y_MIN,Y_MIN_ENDSTOP_INVERTING,3,3) | ||||
|   #endif | ||||
|   #if PIN_EXISTS(Z_MIN) | ||||
|     PIN_ENABLED ("Z Min",Z_MIN,Z_MIN_ENDSTOP_INVERTING,5,3) | ||||
|   #else | ||||
|     PIN_DISABLED("Z Min",Z_MIN,Z_MIN_ENDSTOP_INVERTING,5,3) | ||||
|   #endif | ||||
|   #if ENABLED(FILAMENT_RUNOUT_SENSOR) && PIN_EXISTS(FIL_RUNOUT) | ||||
|     PIN_ENABLED ("Runout 1",FIL_RUNOUT, FIL_RUNOUT_INVERTING,1,4) | ||||
|   #else | ||||
|     PIN_DISABLED("Runout 1",FIL_RUNOUT, FIL_RUNOUT_INVERTING,1,4) | ||||
|   #endif | ||||
|   #if ENABLED(FILAMENT_RUNOUT_SENSOR) && PIN_EXISTS(FIL_RUNOUT2) | ||||
|     PIN_ENABLED ("Runout 2",FIL_RUNOUT2,FIL_RUNOUT_INVERTING,3,4) | ||||
|   #else | ||||
|     PIN_DISABLED("Runout 2",FIL_RUNOUT2,FIL_RUNOUT_INVERTING,3,4) | ||||
|   #endif | ||||
|   #if PIN_EXISTS(Z_MIN_PROBE) | ||||
|     PIN_ENABLED ("Z Probe",Z_MIN_PROBE,Z_MIN_PROBE_ENDSTOP_INVERTING,5,4) | ||||
|   #else | ||||
|     PIN_DISABLED("Z Probe",Z_MIN_PROBE,Z_MIN_PROBE_ENDSTOP_INVERTING,5,4) | ||||
|   #endif | ||||
|  | ||||
|   #if HAS_SOFTWARE_ENDSTOPS | ||||
|     #undef EDGE_R | ||||
|     #define EDGE_R 30 | ||||
|     cmd.font(font_small) | ||||
|        .text         (BTN_POS(1,5), BTN_SIZE(3,1), F("Soft Limits:"), OPT_RIGHTX | OPT_CENTERY) | ||||
|        .colors(ui_toggle) | ||||
|        .tag(2).toggle(BTN_POS(4,5), BTN_SIZE(3,1), F("off\xFFon"), getSoftEndstopState()); | ||||
|       #undef EDGE_R | ||||
|       #define EDGE_R 0 | ||||
|   #endif | ||||
|  | ||||
|   cmd.font(font_medium) | ||||
|      .colors(action_btn) | ||||
|      .tag(1).button( BTN_POS(1,7), BTN_SIZE(6,1), F("Back")); | ||||
|   #undef GRID_COLS | ||||
|   #undef GRID_ROWS | ||||
| } | ||||
|  | ||||
| bool EndstopStatesScreen::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS(); break; | ||||
|     #if HAS_SOFTWARE_ENDSTOPS | ||||
|     case 2: setSoftEndstopState(!getSoftEndstopState()); | ||||
|     #endif | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void EndstopStatesScreen::onIdle() { | ||||
|   constexpr uint32_t DIAGNOSTICS_UPDATE_INTERVAL = 100; | ||||
|  | ||||
|   if (refresh_timer.elapsed(DIAGNOSTICS_UPDATE_INTERVAL)) { | ||||
|     onRefresh(); | ||||
|     refresh_timer.start(); | ||||
|     reset_menu_timeout(); | ||||
|   } | ||||
|   BaseScreen::onIdle(); | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,52 @@ | ||||
| /******************************* | ||||
|  * feedrate_percent_screen.cpp * | ||||
|  *******************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
|  | ||||
| void FeedratePercentScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.precision(0).units(PSTR("%")); | ||||
|  | ||||
|   w.heading(PSTR("Print Speed")); | ||||
|   w.adjuster(4,  PSTR("Speed"), getFeedrate_percent()); | ||||
|   w.increments(); | ||||
| } | ||||
|  | ||||
| bool FeedratePercentScreen::onTouchHeld(uint8_t tag) { | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case 4: UI_DECREMENT(Feedrate_percent); break; | ||||
|     case 5: UI_INCREMENT(Feedrate_percent); break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,101 @@ | ||||
| /********************* | ||||
|  * filament_menu.cpp * | ||||
|  *********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ANY(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void FilamentMenu::onRedraw(draw_mode_t what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|       cmd.font(font_large) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       #define GRID_ROWS 9 | ||||
|       #define GRID_COLS 2 | ||||
|          .text  ( BTN_POS(1,1),      BTN_SIZE(2,1), F("Filament Options:")) | ||||
|          .font(font_medium).colors(normal_btn) | ||||
|       #if ENABLED(FILAMENT_RUNOUT_SENSOR) | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(2).button( BTN_POS(1,2),  BTN_SIZE(2,1), F("Runout Sensor")) | ||||
|       #if ENABLED(LIN_ADVANCE) | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(3).button( BTN_POS(1,3),  BTN_SIZE(2,1), F("Linear Advance")) | ||||
|       .colors(action_btn) | ||||
|       .tag(1) .button( BTN_POS(1,9), BTN_SIZE(2,1), F("Back")); | ||||
|       #undef GRID_COLS | ||||
|       #undef GRID_ROWS | ||||
|     #else | ||||
|       #define GRID_ROWS 6 | ||||
|       #define GRID_COLS 3 | ||||
|          .text  ( BTN_POS(1,1),      BTN_SIZE(3,1), F("Filament Options:")) | ||||
|          .font(font_medium).colors(normal_btn) | ||||
|       #if ENABLED(FILAMENT_RUNOUT_SENSOR) | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(2).button( BTN_POS(1,2),  BTN_SIZE(3,1), F("Filament Runout")) | ||||
|       #if ENABLED(LIN_ADVANCE) | ||||
|         .enabled(1) | ||||
|       #else | ||||
|         .enabled(0) | ||||
|       #endif | ||||
|       .tag(3).button( BTN_POS(1,3),  BTN_SIZE(3,1), F("Linear Advance")) | ||||
|       .colors(action_btn) | ||||
|       .tag(1) .button( BTN_POS(1,6), BTN_SIZE(3,1), F("Back")); | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool FilamentMenu::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS();                   break; | ||||
|     #if ENABLED(FILAMENT_RUNOUT_SENSOR) | ||||
|     case 2: GOTO_SCREEN(FilamentRunoutScreen); break; | ||||
|     #endif | ||||
|     #if ENABLED(LIN_ADVANCE) | ||||
|     case 3: GOTO_SCREEN(LinearAdvanceScreen);  break; | ||||
|     #endif | ||||
|     default: return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,65 @@ | ||||
| /****************************** | ||||
|  * filament_runout_screen.cpp * | ||||
|  ******************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ENABLED(FILAMENT_RUNOUT_SENSOR) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void FilamentRunoutScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.heading(   PSTR("Runout Detection:")); | ||||
|   w.toggle( 2, PSTR("Filament Sensor:"), PSTR("off\xFFon"), getFilamentRunoutEnabled()); | ||||
|  | ||||
|   #ifdef FILAMENT_RUNOUT_DISTANCE_MM | ||||
|     w.heading(PSTR("Detection Threshold:")); | ||||
|     w.units(PSTR("mm")); | ||||
|     w.precision(0); | ||||
|     w.color(e_axis); | ||||
|     w.adjuster( 10, PSTR("Distance:"), getFilamentRunoutDistance_mm(), getFilamentRunoutEnabled()); | ||||
|     w.increments(); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| bool FilamentRunoutScreen::onTouchHeld(uint8_t tag) { | ||||
|   using namespace ExtUI; | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case 2: setFilamentRunoutEnabled(!getFilamentRunoutEnabled()); break; | ||||
|     #ifdef FILAMENT_RUNOUT_DISTANCE_MM | ||||
|       case  10: UI_DECREMENT(FilamentRunoutDistance_mm); break; | ||||
|       case  11: UI_INCREMENT(FilamentRunoutDistance_mm); break; | ||||
|     #endif | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|  | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,264 @@ | ||||
| /******************** | ||||
|  * files_screen.cpp * | ||||
|  ********************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void FilesScreen::onEntry() { | ||||
|   screen_data.FilesScreen.cur_page        = 0; | ||||
|   screen_data.FilesScreen.selected_tag    = 0xFF; | ||||
|   #if ENABLED(SCROLL_LONG_FILENAMES) && (FTDI_API_LEVEL >= 810) | ||||
|     CLCD::mem_write_32(CLCD::REG::MACRO_0,DL::NOP); | ||||
|   #endif | ||||
|   gotoPage(0); | ||||
|   BaseScreen::onEntry(); | ||||
| } | ||||
|  | ||||
| const char *FilesScreen::getSelectedShortFilename() { | ||||
|   FileList files; | ||||
|   files.seek(getFileForTag(screen_data.FilesScreen.selected_tag), true); | ||||
|   return files.shortFilename(); | ||||
| } | ||||
|  | ||||
| const char *FilesScreen::getSelectedLongFilename() { | ||||
|   FileList files; | ||||
|   files.seek(getFileForTag(screen_data.FilesScreen.selected_tag), true); | ||||
|   return files.longFilename(); | ||||
| } | ||||
|  | ||||
| void FilesScreen::drawSelectedFile() { | ||||
|   FileList files; | ||||
|   files.seek(getFileForTag(screen_data.FilesScreen.selected_tag), true); | ||||
|   screen_data.FilesScreen.flags.is_dir = files.isDir(); | ||||
|   drawFileButton( | ||||
|     files.filename(), | ||||
|     screen_data.FilesScreen.selected_tag, | ||||
|     screen_data.FilesScreen.flags.is_dir, | ||||
|     true | ||||
|   ); | ||||
| } | ||||
|  | ||||
| uint16_t FilesScreen::getFileForTag(uint8_t tag) { | ||||
|   return screen_data.FilesScreen.cur_page * files_per_page + tag - 2; | ||||
| } | ||||
|  | ||||
| #ifdef TOUCH_UI_PORTRAIT | ||||
|   #define GRID_COLS  6 | ||||
|   #define GRID_ROWS (files_per_page + header_h + footer_h) | ||||
| #else | ||||
|   #define GRID_COLS  6 | ||||
|   #define GRID_ROWS (files_per_page + header_h + footer_h) | ||||
| #endif | ||||
|  | ||||
| void FilesScreen::drawFileButton(const char* filename, uint8_t tag, bool is_dir, bool is_highlighted) { | ||||
|   const uint8_t line = getLineForTag(tag)+1; | ||||
|   CommandProcessor cmd; | ||||
|   cmd.tag(tag); | ||||
|   cmd.cmd(COLOR_RGB(is_highlighted ? fg_action : bg_color)); | ||||
|   cmd.font(font_medium) | ||||
|      .rectangle( 0, BTN_Y(header_h+line), display_width, BTN_H(1)); | ||||
|   cmd.cmd(COLOR_RGB(is_highlighted ? normal_btn.rgb : bg_text_enabled)); | ||||
|   #if ENABLED(SCROLL_LONG_FILENAMES) | ||||
|     if (is_highlighted) { | ||||
|       cmd.cmd(SAVE_CONTEXT()); | ||||
|       cmd.cmd(MACRO(0)); | ||||
|     } | ||||
|   #endif | ||||
|   cmd.text  (BTN_POS(1,header_h+line), BTN_SIZE(6,1), filename, OPT_CENTERY); | ||||
|   if (is_dir) { | ||||
|     cmd.text(BTN_POS(1,header_h+line), BTN_SIZE(6,1), F("> "),  OPT_CENTERY | OPT_RIGHTX); | ||||
|   } | ||||
|   #if ENABLED(SCROLL_LONG_FILENAMES) | ||||
|     if (is_highlighted) { | ||||
|       cmd.cmd(RESTORE_CONTEXT()); | ||||
|     } | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void FilesScreen::drawFileList() { | ||||
|   FileList files; | ||||
|   screen_data.FilesScreen.num_page = max(1,(ceil)(float(files.count()) / files_per_page)); | ||||
|   screen_data.FilesScreen.cur_page = min(screen_data.FilesScreen.cur_page, screen_data.FilesScreen.num_page-1); | ||||
|   screen_data.FilesScreen.flags.is_root  = files.isAtRootDir(); | ||||
|  | ||||
|   #undef MARGIN_T | ||||
|   #undef MARGIN_B | ||||
|   #define MARGIN_T 0 | ||||
|   #define MARGIN_B 0 | ||||
|   uint16_t fileIndex = screen_data.FilesScreen.cur_page * files_per_page; | ||||
|   for(uint8_t i = 0; i < files_per_page; i++, fileIndex++) { | ||||
|     if (files.seek(fileIndex)) { | ||||
|       drawFileButton(files.filename(), getTagForLine(i), files.isDir(), false); | ||||
|     } else { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void FilesScreen::drawHeader() { | ||||
|   const bool prev_enabled = screen_data.FilesScreen.cur_page > 0; | ||||
|   const bool next_enabled = screen_data.FilesScreen.cur_page < (screen_data.FilesScreen.num_page - 1); | ||||
|  | ||||
|   #undef MARGIN_T | ||||
|   #undef MARGIN_B | ||||
|   #define MARGIN_T 0 | ||||
|   #define MARGIN_B 2 | ||||
|  | ||||
|   char str[16]; | ||||
|   sprintf_P(str, PSTR("Page %d of %d"), | ||||
|     screen_data.FilesScreen.cur_page + 1, screen_data.FilesScreen.num_page); | ||||
|  | ||||
|  | ||||
|   CommandProcessor cmd; | ||||
|   cmd.colors(normal_btn) | ||||
|      .font(font_small) | ||||
|      .tag(0).button( BTN_POS(2,1), BTN_SIZE(4,header_h), str, OPT_CENTER | OPT_FLAT) | ||||
|      .font(font_medium) | ||||
|      .colors(action_btn) | ||||
|      .tag(241).enabled(prev_enabled).button( BTN_POS(1,1), BTN_SIZE(1,header_h), F("<")) | ||||
|      .tag(242).enabled(next_enabled).button( BTN_POS(6,1), BTN_SIZE(1,header_h), F(">")); | ||||
| } | ||||
|  | ||||
| void FilesScreen::drawFooter() { | ||||
|   #undef MARGIN_T | ||||
|   #undef MARGIN_B | ||||
|   #ifdef TOUCH_UI_PORTRAIT | ||||
|   #define MARGIN_T 15 | ||||
|   #define MARGIN_B 5 | ||||
|   #else | ||||
|   #define MARGIN_T 5 | ||||
|   #define MARGIN_B 5 | ||||
|   #endif | ||||
|   const bool    has_selection = screen_data.FilesScreen.selected_tag != 0xFF; | ||||
|   const uint8_t back_tag      = screen_data.FilesScreen.flags.is_root ? 240 : 245; | ||||
|   const uint8_t y             = GRID_ROWS - footer_h + 1; | ||||
|   const uint8_t h             = footer_h; | ||||
|  | ||||
|   CommandProcessor cmd; | ||||
|   cmd.colors(normal_btn) | ||||
|      .font(font_medium) | ||||
|      .colors(has_selection ? normal_btn : action_btn) | ||||
|      .tag(back_tag).button( BTN_POS(4,y), BTN_SIZE(3,h), F("Back")) | ||||
|      .enabled(has_selection) | ||||
|      .colors(has_selection ? action_btn : normal_btn); | ||||
|   if (screen_data.FilesScreen.flags.is_dir) { | ||||
|     cmd.tag(244).button( BTN_POS(1, y), BTN_SIZE(3,h), F("Open")); | ||||
|   } else { | ||||
|     cmd.tag(243).button( BTN_POS(1, y), BTN_SIZE(3,h), F("Print")); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void FilesScreen::onRedraw(draw_mode_t what) { | ||||
|   if (what & FOREGROUND) { | ||||
|     drawHeader(); | ||||
|     drawSelectedFile(); | ||||
|     drawFooter(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void FilesScreen::gotoPage(uint8_t page) { | ||||
|   screen_data.FilesScreen.selected_tag = 0xFF; | ||||
|   screen_data.FilesScreen.cur_page     = page; | ||||
|   CommandProcessor cmd; | ||||
|   cmd.cmd(CMD_DLSTART) | ||||
|      .cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|      .cmd(CLEAR(true,true,true)) | ||||
|      .colors(normal_btn); | ||||
|   drawFileList(); | ||||
|   storeBackground(); | ||||
| } | ||||
|  | ||||
| bool FilesScreen::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 240: GOTO_PREVIOUS();                  return true; | ||||
|     case 241: | ||||
|       if (screen_data.FilesScreen.cur_page > 0) { | ||||
|         gotoPage(screen_data.FilesScreen.cur_page-1); | ||||
|       } | ||||
|       break; | ||||
|     case 242: | ||||
|       if (screen_data.FilesScreen.cur_page < (screen_data.FilesScreen.num_page-1)) { | ||||
|         gotoPage(screen_data.FilesScreen.cur_page+1); | ||||
|       } | ||||
|       break; | ||||
|     case 243: | ||||
|       printFile(getSelectedShortFilename()); | ||||
|       StatusScreen::setStatusMessage(F("Print Starting")); | ||||
|       GOTO_SCREEN(StatusScreen); | ||||
|       return true; | ||||
|     case 244: | ||||
|       { | ||||
|         FileList files; | ||||
|         files.changeDir(getSelectedShortFilename()); | ||||
|         gotoPage(0); | ||||
|       } | ||||
|       break; | ||||
|     case 245: | ||||
|       { | ||||
|         FileList files; | ||||
|         files.upDir(); | ||||
|         gotoPage(0); | ||||
|       } | ||||
|       break; | ||||
|     default: | ||||
|       if (tag < 240) { | ||||
|         screen_data.FilesScreen.selected_tag = tag; | ||||
|         #if ENABLED(SCROLL_LONG_FILENAMES) && (FTDI_API_LEVEL >= 810) | ||||
|           if (FTDI::ftdi_chip >= 810) { | ||||
|             const char *longFilename = getSelectedLongFilename(); | ||||
|             if (longFilename[0]) { | ||||
|               CLCD::FontMetrics fm(font_medium); | ||||
|               uint16_t text_width = fm.get_text_width(longFilename); | ||||
|               screen_data.FilesScreen.scroll_pos = 0; | ||||
|               if (text_width > display_width) | ||||
|                 screen_data.FilesScreen.scroll_max = text_width - display_width + MARGIN_L + MARGIN_R; | ||||
|               else | ||||
|                 screen_data.FilesScreen.scroll_max = 0; | ||||
|             } | ||||
|           } | ||||
|         #endif | ||||
|       } | ||||
|       break; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void FilesScreen::onIdle() { | ||||
|   #if ENABLED(SCROLL_LONG_FILENAMES) && (FTDI_API_LEVEL >= 810) | ||||
|     if (FTDI::ftdi_chip >= 810) { | ||||
|       CLCD::mem_write_32(CLCD::REG::MACRO_0, | ||||
|         VERTEX_TRANSLATE_X(-int32_t(screen_data.FilesScreen.scroll_pos))); | ||||
|       if (screen_data.FilesScreen.scroll_pos < screen_data.FilesScreen.scroll_max * 16) | ||||
|         screen_data.FilesScreen.scroll_pos++; | ||||
|     } | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,285 @@ | ||||
| /********************************* | ||||
|  * interface_settings_screen.cpp * | ||||
|  *********************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| #include "../archim2-flash/flash_storage.h" | ||||
|  | ||||
| #include "../../../../../module/configuration_store.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_PRINTCOUNTER) | ||||
|   #include "../../../../../module/printcounter.h" | ||||
| #endif | ||||
|  | ||||
| bool restoreEEPROM(); | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| constexpr bool PERSISTENT_STORE_SUCCESS = false; // persistentStore uses true for error | ||||
|  | ||||
| void InterfaceSettingsScreen::onStartup() { | ||||
| } | ||||
|  | ||||
| void InterfaceSettingsScreen::onEntry() { | ||||
|   screen_data.InterfaceSettingsScreen.brightness = CLCD::get_brightness(); | ||||
|   screen_data.InterfaceSettingsScreen.volume     = SoundPlayer::get_volume(); | ||||
|   BaseScreen::onEntry(); | ||||
| } | ||||
|  | ||||
| void InterfaceSettingsScreen::onRedraw(draw_mode_t what) { | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|  | ||||
|     #define GRID_COLS 4 | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       #define GRID_ROWS 7 | ||||
|     #else | ||||
|       #define GRID_ROWS 6 | ||||
|     #endif | ||||
|  | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)) | ||||
|        .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .tag(0) | ||||
|        .font(font_medium) | ||||
|        .text(BTN_POS(1,1), BTN_SIZE(4,1), F("Interface Settings")) | ||||
|     #undef EDGE_R | ||||
|     #define EDGE_R 30 | ||||
|        .font(font_small) | ||||
|        .tag(0) | ||||
|        .text(BTN_POS(1,2), BTN_SIZE(2,1), F("LCD brightness:"), OPT_RIGHTX | OPT_CENTERY) | ||||
|        .text(BTN_POS(1,3), BTN_SIZE(2,1), F("Sound volume:"),   OPT_RIGHTX | OPT_CENTERY) | ||||
|        .text(BTN_POS(1,4), BTN_SIZE(2,1), F("Screen lock:"),    OPT_RIGHTX | OPT_CENTERY); | ||||
|     cmd.text(BTN_POS(1,5), BTN_SIZE(2,1), F("Boot screen:"),    OPT_RIGHTX | OPT_CENTERY); | ||||
|     #undef EDGE_R | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       constexpr uint8_t w = 2; | ||||
|     #else | ||||
|       constexpr uint8_t w = 1; | ||||
|     #endif | ||||
|  | ||||
|     cmd.font(font_medium) | ||||
|     #define EDGE_R 30 | ||||
|        .colors(ui_slider) | ||||
|        .tag(2).slider(BTN_POS(3,2), BTN_SIZE(2,1), screen_data.InterfaceSettingsScreen.brightness, 128) | ||||
|        .tag(3).slider(BTN_POS(3,3), BTN_SIZE(2,1), screen_data.InterfaceSettingsScreen.volume,     0xFF) | ||||
|        .colors(ui_toggle) | ||||
|        .tag(4).toggle(BTN_POS(3,4), BTN_SIZE(w,1), F("off\xFFon"), LockScreen::is_enabled()) | ||||
|        .tag(5).toggle(BTN_POS(3,5), BTN_SIZE(w,1), F("off\xFFon"), UIData::animations_enabled()) | ||||
|     #undef EDGE_R | ||||
|     #define EDGE_R 0 | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|        .colors(normal_btn) | ||||
|        .tag(6).button (BTN_POS(1,6), BTN_SIZE(4,1), F("Customize Sounds")) | ||||
|        .colors(action_btn) | ||||
|        .tag(1).button (BTN_POS(1,7), BTN_SIZE(4,1), F("Back")); | ||||
|     #else | ||||
|        .tag(6).button (BTN_POS(1,6), BTN_SIZE(2,1), F("Customize Sounds")) | ||||
|        .colors(action_btn) | ||||
|        .tag(1).button (BTN_POS(3,6), BTN_SIZE(2,1), F("Back")); | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool InterfaceSettingsScreen::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS(); return true; | ||||
|     case 4: | ||||
|       if (!LockScreen::is_enabled()) | ||||
|         LockScreen::enable(); | ||||
|       else | ||||
|         LockScreen::disable(); | ||||
|       break; | ||||
|     case 5: UIData::enable_animations(!UIData::animations_enabled());; break; | ||||
|     case 6: GOTO_SCREEN(InterfaceSoundsScreen); return true; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool InterfaceSettingsScreen::onTouchStart(uint8_t tag) { | ||||
|   #undef EDGE_R | ||||
|   #define EDGE_R 30 | ||||
|   CommandProcessor cmd; | ||||
|   switch (tag) { | ||||
|     case 2: cmd.track_linear(BTN_POS(3,3), BTN_SIZE(2,1), 2).execute(); break; | ||||
|     case 3: cmd.track_linear(BTN_POS(3,4), BTN_SIZE(2,1), 3).execute(); break; | ||||
|     default: break; | ||||
|   } | ||||
|   #undef EDGE_R | ||||
|   #define EDGE_R 0 | ||||
|   #undef GRID_COLS | ||||
|   #undef GRID_ROWS | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void InterfaceSettingsScreen::onIdle() { | ||||
|   if (refresh_timer.elapsed(TOUCH_UPDATE_INTERVAL)) { | ||||
|     refresh_timer.start(); | ||||
|  | ||||
|     uint16_t value; | ||||
|     CommandProcessor cmd; | ||||
|     switch (cmd.track_tag(value)) { | ||||
|       case 2: | ||||
|         screen_data.InterfaceSettingsScreen.brightness = float(value) * 128 / 0xFFFF; | ||||
|         CLCD::set_brightness(screen_data.InterfaceSettingsScreen.brightness); | ||||
|         SaveSettingsDialogBox::settingsChanged(); | ||||
|         break; | ||||
|       case 3: | ||||
|         screen_data.InterfaceSettingsScreen.volume = value >> 8; | ||||
|         SoundPlayer::set_volume(screen_data.InterfaceSettingsScreen.volume); | ||||
|         SaveSettingsDialogBox::settingsChanged(); | ||||
|         break; | ||||
|       default: | ||||
|         return; | ||||
|     } | ||||
|     onRefresh(); | ||||
|   } | ||||
|   BaseScreen::onIdle(); | ||||
| } | ||||
|  | ||||
| void InterfaceSettingsScreen::failSafeSettings() { | ||||
|   // Reset settings that may make the printer interface | ||||
|   // unusable. | ||||
|   CLCD::mem_write_32(CLCD::REG::ROTATE, 0); | ||||
|   CLCD::default_touch_transform(); | ||||
|   CLCD::default_display_orientation(); | ||||
|   CLCD::set_brightness(255); | ||||
|   UIData::reset_persistent_data(); | ||||
|   CLCD::mem_write_16(CLCD::REG::HOFFSET, FTDI::Hoffset); | ||||
|   CLCD::mem_write_16(CLCD::REG::VOFFSET, FTDI::Voffset); | ||||
| } | ||||
|  | ||||
| void InterfaceSettingsScreen::defaultSettings() { | ||||
|   LockScreen::passcode = 0; | ||||
|   SoundPlayer::set_volume(255); | ||||
|   CLCD::set_brightness(255); | ||||
|   UIData::reset_persistent_data(); | ||||
|   InterfaceSoundsScreen::defaultSettings(); | ||||
|   CLCD::mem_write_16(CLCD::REG::HOFFSET, FTDI::Hoffset); | ||||
|   CLCD::mem_write_16(CLCD::REG::VOFFSET, FTDI::Voffset); | ||||
| } | ||||
|  | ||||
| void InterfaceSettingsScreen::saveSettings(char *buff) { | ||||
|   static_assert( | ||||
|     ExtUI::eeprom_data_size >= sizeof(persistent_data_t), | ||||
|     "Insufficient space in EEPROM for UI parameters" | ||||
|   ); | ||||
|  | ||||
|   SERIAL_ECHOLNPGM("Writing setting to EEPROM"); | ||||
|  | ||||
|   persistent_data_t eeprom; | ||||
|  | ||||
|   eeprom.passcode             = LockScreen::passcode; | ||||
|   eeprom.sound_volume         = SoundPlayer::get_volume(); | ||||
|   eeprom.display_brightness   = CLCD::get_brightness(); | ||||
|   eeprom.bit_flags            = UIData::get_persistent_data(); | ||||
|   eeprom.touch_transform_a    = CLCD::mem_read_32(CLCD::REG::TOUCH_TRANSFORM_A); | ||||
|   eeprom.touch_transform_b    = CLCD::mem_read_32(CLCD::REG::TOUCH_TRANSFORM_B); | ||||
|   eeprom.touch_transform_c    = CLCD::mem_read_32(CLCD::REG::TOUCH_TRANSFORM_C); | ||||
|   eeprom.touch_transform_d    = CLCD::mem_read_32(CLCD::REG::TOUCH_TRANSFORM_D); | ||||
|   eeprom.touch_transform_e    = CLCD::mem_read_32(CLCD::REG::TOUCH_TRANSFORM_E); | ||||
|   eeprom.touch_transform_f    = CLCD::mem_read_32(CLCD::REG::TOUCH_TRANSFORM_F); | ||||
|   eeprom.display_h_offset_adj = CLCD::mem_read_16(CLCD::REG::HOFFSET) - FTDI::Hoffset; | ||||
|   eeprom.display_v_offset_adj = CLCD::mem_read_16(CLCD::REG::VOFFSET) - FTDI::Voffset; | ||||
|   for(uint8_t i = 0; i < InterfaceSoundsScreen::NUM_EVENTS; i++) | ||||
|     eeprom.event_sounds[i] = InterfaceSoundsScreen::event_sounds[i]; | ||||
|  | ||||
|   memcpy(buff, &eeprom, sizeof(eeprom)); | ||||
| } | ||||
|  | ||||
| void InterfaceSettingsScreen::loadSettings(const char *buff) { | ||||
|   static_assert( | ||||
|     ExtUI::eeprom_data_size >= sizeof(persistent_data_t), | ||||
|     "Insufficient space in EEPROM for UI parameters" | ||||
|   ); | ||||
|  | ||||
|   persistent_data_t eeprom; | ||||
|   memcpy(&eeprom, buff, sizeof(eeprom)); | ||||
|  | ||||
|   SERIAL_ECHOLNPGM("Loading setting from EEPROM"); | ||||
|  | ||||
|   LockScreen::passcode = eeprom.passcode; | ||||
|   SoundPlayer::set_volume(eeprom.sound_volume); | ||||
|   UIData::set_persistent_data(eeprom.bit_flags); | ||||
|   CLCD::set_brightness(eeprom.display_brightness); | ||||
|   CLCD::mem_write_32(CLCD::REG::TOUCH_TRANSFORM_A, eeprom.touch_transform_a); | ||||
|   CLCD::mem_write_32(CLCD::REG::TOUCH_TRANSFORM_B, eeprom.touch_transform_b); | ||||
|   CLCD::mem_write_32(CLCD::REG::TOUCH_TRANSFORM_C, eeprom.touch_transform_c); | ||||
|   CLCD::mem_write_32(CLCD::REG::TOUCH_TRANSFORM_D, eeprom.touch_transform_d); | ||||
|   CLCD::mem_write_32(CLCD::REG::TOUCH_TRANSFORM_E, eeprom.touch_transform_e); | ||||
|   CLCD::mem_write_32(CLCD::REG::TOUCH_TRANSFORM_F, eeprom.touch_transform_f); | ||||
|   CLCD::mem_write_16(CLCD::REG::HOFFSET,           eeprom.display_h_offset_adj + FTDI::Hoffset); | ||||
|   CLCD::mem_write_16(CLCD::REG::VOFFSET,           eeprom.display_v_offset_adj + FTDI::Voffset); | ||||
|   for(uint8_t i = 0; i < InterfaceSoundsScreen::NUM_EVENTS; i++) | ||||
|     InterfaceSoundsScreen::event_sounds[i] = eeprom.event_sounds[i]; | ||||
|  | ||||
|   #if ENABLED(DEVELOPER_SCREENS) | ||||
|     StressTestScreen::startupCheck(); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #ifdef LULZBOT_EEPROM_BACKUP_SIZE | ||||
|   #include "../../../../../HAL/shared/persistent_store_api.h" | ||||
|  | ||||
|   bool restoreEEPROM() { | ||||
|     uint8_t data[LULZBOT_EEPROM_BACKUP_SIZE]; | ||||
|  | ||||
|     bool success = UIFlashStorage::read_config_data(data, LULZBOT_EEPROM_BACKUP_SIZE); | ||||
|  | ||||
|     if (success) | ||||
|       success = persistentStore.write_data(0, data, LULZBOT_EEPROM_BACKUP_SIZE) == PERSISTENT_STORE_SUCCESS; | ||||
|  | ||||
|     if (success) | ||||
|       StatusScreen::setStatusMessage(F("Settings restored from backup")); | ||||
|     else | ||||
|       StatusScreen::setStatusMessage(F("Settings restored to default")); | ||||
|  | ||||
|     return success; | ||||
|   } | ||||
|  | ||||
|   bool InterfaceSettingsScreen::backupEEPROM() { | ||||
|     uint8_t data[LULZBOT_EEPROM_BACKUP_SIZE]; | ||||
|  | ||||
|     if (persistentStore.read_data(0, data, LULZBOT_EEPROM_BACKUP_SIZE) != PERSISTENT_STORE_SUCCESS) | ||||
|       return false; | ||||
|  | ||||
|     UIFlashStorage::write_config_data(data, LULZBOT_EEPROM_BACKUP_SIZE); | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,160 @@ | ||||
| /******************************* | ||||
|  * interface_sounds_screen.cpp * | ||||
|  *******************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
| using namespace ExtUI; | ||||
|  | ||||
| uint8_t InterfaceSoundsScreen::event_sounds[]; | ||||
|  | ||||
| const char* InterfaceSoundsScreen::getSoundSelection(event_t event) { | ||||
|   return SoundList::name(event_sounds[event]); | ||||
| } | ||||
|  | ||||
| void InterfaceSoundsScreen::toggleSoundSelection(event_t event) { | ||||
|   event_sounds[event] = (event_sounds[event]+1) % SoundList::n; | ||||
|   playEventSound(event); | ||||
| } | ||||
|  | ||||
| void InterfaceSoundsScreen::setSoundSelection(event_t event, const SoundPlayer::sound_t* sound) { | ||||
|   for(uint8_t i = 0; i < SoundList::n; i++) | ||||
|     if (SoundList::data(i) == sound) | ||||
|       event_sounds[event] = i; | ||||
| } | ||||
|  | ||||
| void InterfaceSoundsScreen::playEventSound(event_t event, play_mode_t mode) { | ||||
|   sound.play(SoundList::data(event_sounds[event]), mode); | ||||
| } | ||||
|  | ||||
| void InterfaceSoundsScreen::defaultSettings() { | ||||
|   setSoundSelection(PRINTING_STARTED,  twinkle); | ||||
|   setSoundSelection(PRINTING_FINISHED, fanfare); | ||||
|   setSoundSelection(PRINTING_FAILED,   sad_trombone); | ||||
| } | ||||
|  | ||||
| void InterfaceSoundsScreen::onRedraw(draw_mode_t what) { | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)) | ||||
|        .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        .tag(0) | ||||
|  | ||||
|     #define GRID_COLS 4 | ||||
|     #define GRID_ROWS 9 | ||||
|  | ||||
|        .font(font_medium) | ||||
|        .text(BTN_POS(1,1), BTN_SIZE(4,1), F("Interface Sounds")) | ||||
|     #undef EDGE_R | ||||
|     #define EDGE_R 30 | ||||
|        .font(font_small) | ||||
|        .tag(0).text      (BTN_POS(1,2), BTN_SIZE(2,1), F("Sound volume:"),   OPT_RIGHTX | OPT_CENTERY) | ||||
|               .text      (BTN_POS(1,3), BTN_SIZE(2,1), F("Click sounds:"),   OPT_RIGHTX | OPT_CENTERY) | ||||
|               .text      (BTN_POS(1,5), BTN_SIZE(2,1), F("Print starting:"), OPT_RIGHTX | OPT_CENTERY) | ||||
|               .text      (BTN_POS(1,6), BTN_SIZE(2,1), F("Print finished:"), OPT_RIGHTX | OPT_CENTERY) | ||||
|               .text      (BTN_POS(1,7), BTN_SIZE(2,1), F("Print error:"),    OPT_RIGHTX | OPT_CENTERY); | ||||
|     #undef EDGE_R | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       constexpr uint8_t w = 2; | ||||
|     #else | ||||
|       constexpr uint8_t w = 1; | ||||
|     #endif | ||||
|  | ||||
|     cmd.font(font_medium) | ||||
|        .colors(ui_slider) | ||||
|     #define EDGE_R 30 | ||||
|        .tag(2).slider    (BTN_POS(3,2), BTN_SIZE(2,1), screen_data.InterfaceSettingsScreen.volume, 0xFF) | ||||
|        .colors(ui_toggle) | ||||
|        .tag(3).toggle    (BTN_POS(3,3), BTN_SIZE(w,1), F("off\xFFon"), UIData::touch_sounds_enabled()) | ||||
|     #undef EDGE_R | ||||
|        .colors(normal_btn) | ||||
|     #define EDGE_R 0 | ||||
|        .tag(4).button    (BTN_POS(3,5), BTN_SIZE(2,1), getSoundSelection(PRINTING_STARTED)) | ||||
|        .tag(5).button    (BTN_POS(3,6), BTN_SIZE(2,1), getSoundSelection(PRINTING_FINISHED)) | ||||
|        .tag(6).button    (BTN_POS(3,7), BTN_SIZE(2,1), getSoundSelection(PRINTING_FAILED)) | ||||
|        .colors(action_btn) | ||||
|        .tag(1).button    (BTN_POS(1,9), BTN_SIZE(4,1), F("Back")); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void InterfaceSoundsScreen::onEntry() { | ||||
|   screen_data.InterfaceSettingsScreen.volume = SoundPlayer::get_volume(); | ||||
|   BaseScreen::onEntry(); | ||||
| } | ||||
|  | ||||
| bool InterfaceSoundsScreen::onTouchEnd(uint8_t tag) { | ||||
|   switch (tag) { | ||||
|     case 1: GOTO_PREVIOUS();                                              return true; | ||||
|     case 3: UIData::enable_touch_sounds(!UIData::touch_sounds_enabled()); break; | ||||
|     case 4: toggleSoundSelection(PRINTING_STARTED);                       break; | ||||
|     case 5: toggleSoundSelection(PRINTING_FINISHED);                      break; | ||||
|     case 6: toggleSoundSelection(PRINTING_FAILED);                        break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool InterfaceSoundsScreen::onTouchStart(uint8_t tag) { | ||||
|   CommandProcessor cmd; | ||||
|   #undef EDGE_R | ||||
|   #define EDGE_R 30 | ||||
|   switch (tag) { | ||||
|     case 2: cmd.track_linear(BTN_POS(3,2), BTN_SIZE(2,1), 2).execute(); break; | ||||
|     default: break; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void InterfaceSoundsScreen::onIdle() { | ||||
|   if (refresh_timer.elapsed(TOUCH_UPDATE_INTERVAL)) { | ||||
|     refresh_timer.start(); | ||||
|  | ||||
|     uint16_t value; | ||||
|     CommandProcessor cmd; | ||||
|     switch (cmd.track_tag(value)) { | ||||
|       case 2: | ||||
|         screen_data.InterfaceSettingsScreen.volume = value >> 8; | ||||
|         SoundPlayer::set_volume(screen_data.InterfaceSettingsScreen.volume); | ||||
|         SaveSettingsDialogBox::settingsChanged(); | ||||
|         break; | ||||
|       default: | ||||
|         return; | ||||
|     } | ||||
|     onRefresh(); | ||||
|   } | ||||
|   BaseScreen::onIdle(); | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,65 @@ | ||||
| /******************* | ||||
|  * jerk_screen.cpp * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && DISABLED(JUNCTION_DEVIATION) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void JerkScreen::onRedraw(draw_mode_t what) { | ||||
|  | ||||
|   widgets_t w(what); | ||||
|   w.precision(1); | ||||
|   w.units(PSTR("mm/s")); | ||||
|   w.heading(                           PSTR("Maximum Jerk")); | ||||
|   w.color(x_axis) .adjuster( 2, PSTR("X:"), getAxisMaxJerk_mm_s(X) ); | ||||
|   w.color(y_axis) .adjuster( 4, PSTR("Y:"), getAxisMaxJerk_mm_s(Y) ); | ||||
|   w.color(z_axis) .adjuster( 6, PSTR("Z:"), getAxisMaxJerk_mm_s(Z) ); | ||||
|   w.color(e_axis) .adjuster( 8, PSTR("E:"), getAxisMaxJerk_mm_s(E0) ); | ||||
|   w.increments(); | ||||
| } | ||||
|  | ||||
| bool JerkScreen::onTouchHeld(uint8_t tag) { | ||||
|   using namespace ExtUI; | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case  2: UI_DECREMENT(AxisMaxJerk_mm_s, X); break; | ||||
|     case  3: UI_INCREMENT(AxisMaxJerk_mm_s, X); break; | ||||
|     case  4: UI_DECREMENT(AxisMaxJerk_mm_s, Y); break; | ||||
|     case  5: UI_INCREMENT(AxisMaxJerk_mm_s, Y); break; | ||||
|     case  6: UI_DECREMENT(AxisMaxJerk_mm_s, Z); break; | ||||
|     case  7: UI_INCREMENT(AxisMaxJerk_mm_s, Z); break; | ||||
|     case  8: UI_DECREMENT(AxisMaxJerk_mm_s, E0); break; | ||||
|     case  9: UI_INCREMENT(AxisMaxJerk_mm_s, E0); break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,54 @@ | ||||
| /******************* | ||||
|  * boot_screen.cpp * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ENABLED(JUNCTION_DEVIATION) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void JunctionDeviationScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.precision(2); | ||||
|   w.units(PSTR("mm")); | ||||
|   w.heading(                          PSTR("Junction Deviation")); | ||||
|   w.color(other) .adjuster( 2, PSTR(""), getJunctionDeviation_mm() ); | ||||
|   w.increments(); | ||||
| } | ||||
|  | ||||
| bool JunctionDeviationScreen::onTouchHeld(uint8_t tag) { | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case  2: UI_DECREMENT(JunctionDeviation_mm); break; | ||||
|     case  3: UI_INCREMENT(JunctionDeviation_mm); break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,62 @@ | ||||
| /******************* | ||||
|  * kill_screen.cpp * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
|  | ||||
| // The kill screen is an oddball that happens after Marlin has killed the events | ||||
| // loop. So we only have a show() method rather than onRedraw(). The KillScreen | ||||
| // should not be used as a model for other UI screens as it is an exception. | ||||
|  | ||||
| void KillScreen::show(progmem_str message) { | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   cmd.cmd(CMD_DLSTART) | ||||
|      .cmd(CLEAR_COLOR_RGB(Theme::bg_color)) | ||||
|      .cmd(CLEAR(true,true,true)) | ||||
|      .tag(0); | ||||
|  | ||||
|   #define GRID_COLS 4 | ||||
|   #define GRID_ROWS 8 | ||||
|  | ||||
|   cmd.font(Theme::font_large) | ||||
|      .cmd(COLOR_RGB(Theme::bg_text_enabled)) | ||||
|      .text(BTN_POS(1,2), BTN_SIZE(4,1), message) | ||||
|      .text(BTN_POS(1,3), BTN_SIZE(4,1), F("PRINTER HALTED")) | ||||
|      .text(BTN_POS(1,6), BTN_SIZE(4,1), F("Please reset")); | ||||
|  | ||||
|   #undef GRID_COLS | ||||
|   #undef GRID_ROWS | ||||
|  | ||||
|   cmd.cmd(DL::DL_DISPLAY) | ||||
|      .cmd(CMD_SWAP) | ||||
|      .execute(); | ||||
|  | ||||
|   InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED, PLAY_SYNCHRONOUS); | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,77 @@ | ||||
| /***************************** | ||||
|  * linear_advance_screen.cpp * | ||||
|  *****************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && ENABLED(LIN_ADVANCE) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void LinearAdvanceScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.precision(2, DEFAULT_LOWEST).color(e_axis); | ||||
|   w.heading(           PSTR("Linear Advance:")); | ||||
|   #if EXTRUDERS == 1 | ||||
|     w.adjuster(     2, PSTR("K:"),    getLinearAdvance_mm_mm_s(E0) ); | ||||
|   #else | ||||
|     w.adjuster(     2, PSTR("K E1:"), getLinearAdvance_mm_mm_s(E0) ); | ||||
|     w.adjuster(     4, PSTR("K E2:"), getLinearAdvance_mm_mm_s(E1) ); | ||||
|     #if EXTRUDERS > 2 | ||||
|       w.adjuster(   6, PSTR("K E3:"), getLinearAdvance_mm_mm_s(E2) ); | ||||
|       #if EXTRUDERS > 3 | ||||
|         w.adjuster( 8, PSTR("K E4:"), getLinearAdvance_mm_mm_s(E3) ); | ||||
|       #endif | ||||
|     #endif | ||||
|   #endif | ||||
|   w.increments(); | ||||
| } | ||||
|  | ||||
| bool LinearAdvanceScreen::onTouchHeld(uint8_t tag) { | ||||
|   using namespace ExtUI; | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case  2: UI_DECREMENT(LinearAdvance_mm_mm_s, E0); break; | ||||
|     case  3: UI_INCREMENT(LinearAdvance_mm_mm_s, E0); break; | ||||
|     #if EXTRUDERS > 1 | ||||
|       case  4: UI_DECREMENT(LinearAdvance_mm_mm_s, E1);  break; | ||||
|       case  5: UI_INCREMENT(LinearAdvance_mm_mm_s, E1); break; | ||||
|       #if EXTRUDERS > 2 | ||||
|         case  6: UI_DECREMENT(LinearAdvance_mm_mm_s, E2);  break; | ||||
|         case  7: UI_INCREMENT(LinearAdvance_mm_mm_s, E2);  break; | ||||
|         #if EXTRUDERS > 3 | ||||
|           case  8: UI_DECREMENT(LinearAdvance_mm_mm_s, E3);  break; | ||||
|           case  9: UI_INCREMENT(LinearAdvance_mm_mm_s, E3);  break; | ||||
|         #endif | ||||
|       #endif | ||||
|     #endif | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   SaveSettingsDialogBox::settingsChanged(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
							
								
								
									
										214
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/screens/lock_screen.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/screens/lock_screen.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,214 @@ | ||||
| /******************* | ||||
|  * lock_screen.cpp * | ||||
|  *******************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
| #include "screen_data.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| uint16_t LockScreen::passcode = 0; | ||||
|  | ||||
| void LockScreen::onEntry() { | ||||
|   const uint8_t siz = sizeof(screen_data.LockScreen.passcode); | ||||
|   memset(screen_data.LockScreen.passcode, '_', siz-1); | ||||
|   screen_data.LockScreen.passcode[siz-1] = '\0'; | ||||
|   BaseScreen::onEntry(); | ||||
| } | ||||
|  | ||||
| void LockScreen::onRedraw(draw_mode_t what) { | ||||
|   CommandProcessor cmd; | ||||
|  | ||||
|   if (what & BACKGROUND) { | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)) | ||||
|        .tag(0); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       #define GRID_COLS 1 | ||||
|       #define GRID_ROWS 10 | ||||
|     #else | ||||
|       #define GRID_COLS 1 | ||||
|       #define GRID_ROWS 7 | ||||
|     #endif | ||||
|  | ||||
|     #undef MARGIN_T | ||||
|     #undef MARGIN_B | ||||
|     #define MARGIN_T 3 | ||||
|     #define MARGIN_B 3 | ||||
|  | ||||
|     progmem_str message; | ||||
|     switch (message_style()) { | ||||
|       case 'w': | ||||
|         message = F("Wrong passcode!"); | ||||
|         break; | ||||
|       case 'g': | ||||
|         message = F("Passcode accepted!"); | ||||
|         break; | ||||
|       default: | ||||
|         if (passcode == 0) { | ||||
|           message = F("Select Passcode:"); | ||||
|         } else { | ||||
|           message = F("Enter Passcode:"); | ||||
|         } | ||||
|     } | ||||
|     message_style() = '\0'; // Terminate the string. | ||||
|  | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       constexpr uint8_t l = 6; | ||||
|     #else | ||||
|       constexpr uint8_t l = 3; | ||||
|     #endif | ||||
|  | ||||
|     const uint8_t pressed = EventLoop::get_pressed_tag(); | ||||
|  | ||||
|     cmd.font(font_large) | ||||
|        .cmd(COLOR_RGB(bg_text_enabled)) | ||||
|        #ifdef TOUCH_UI_PORTRAIT | ||||
|        .text(BTN_POS(1,2), BTN_SIZE(1,1), message) | ||||
|        .font(font_xlarge) | ||||
|        .text(BTN_POS(1,4), BTN_SIZE(1,1), screen_data.LockScreen.passcode) | ||||
|        #else | ||||
|        .text(BTN_POS(1,1), BTN_SIZE(1,1), message) | ||||
|        .font(font_xlarge) | ||||
|        .text(BTN_POS(1,2), BTN_SIZE(1,1), screen_data.LockScreen.passcode) | ||||
|        #endif | ||||
|        .font(font_large) | ||||
|        .colors(normal_btn) | ||||
|        #ifdef TOUCH_UI_PASSCODE | ||||
|        .keys(BTN_POS(1,l+1), BTN_SIZE(1,1), F("123"),        pressed) | ||||
|        .keys(BTN_POS(1,l+2), BTN_SIZE(1,1), F("456"),        pressed) | ||||
|        .keys(BTN_POS(1,l+3), BTN_SIZE(1,1), F("789"),        pressed) | ||||
|        .keys(BTN_POS(1,l+4), BTN_SIZE(1,1), F("0.<"),        pressed); | ||||
|        #else | ||||
|        .keys(BTN_POS(1,l+1), BTN_SIZE(1,1), F("1234567890"), pressed) | ||||
|        .keys(BTN_POS(1,l+2), BTN_SIZE(1,1), F("qwertyuiop"), pressed) | ||||
|        .keys(BTN_POS(1,l+3), BTN_SIZE(1,1), F("asdfghjkl "), pressed) | ||||
|        .keys(BTN_POS(1,l+4), BTN_SIZE(1,1), F("zxcvbnm!?<"), pressed); | ||||
|        #endif | ||||
|  | ||||
|     #undef MARGIN_T | ||||
|     #undef MARGIN_B | ||||
|     #define MARGIN_T MARGIN_DEFAULT | ||||
|     #define MARGIN_B MARGIN_DEFAULT | ||||
|  | ||||
|     #undef GRID_COLS | ||||
|     #undef GRID_ROWS | ||||
|   } | ||||
| } | ||||
|  | ||||
| char &LockScreen::message_style() { | ||||
|   // We use the last byte of the passcode string as a flag to indicate, | ||||
|   // which message to show. | ||||
|   constexpr uint8_t last_char = sizeof(screen_data.LockScreen.passcode)-1; | ||||
|   return screen_data.LockScreen.passcode[last_char]; | ||||
| } | ||||
|  | ||||
| void LockScreen::onPasscodeEntered() { | ||||
|   if (passcode == 0) { | ||||
|     // We are defining a passcode | ||||
|     message_style() = 0; | ||||
|     onRefresh(); | ||||
|     sound.play(twinkle, PLAY_SYNCHRONOUS); | ||||
|     passcode = compute_checksum(); | ||||
|     GOTO_PREVIOUS(); | ||||
|   } else { | ||||
|     // We are verifying a passcode | ||||
|     if (passcode == compute_checksum()) { | ||||
|       message_style() = 'g'; | ||||
|       onRefresh(); | ||||
|       sound.play(twinkle, PLAY_SYNCHRONOUS); | ||||
|       GOTO_PREVIOUS(); | ||||
|     } else { | ||||
|       message_style() = 'w'; | ||||
|       onRefresh(); | ||||
|       sound.play(sad_trombone, PLAY_SYNCHRONOUS); | ||||
|       current_screen.forget(); // Discard the screen the user was trying to go to. | ||||
|       GOTO_PREVIOUS(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool LockScreen::onTouchEnd(uint8_t tag) { | ||||
|   char *c = strchr(screen_data.LockScreen.passcode,'_'); | ||||
|   if (c) { | ||||
|     if (tag == '<') { | ||||
|       if (c != screen_data.LockScreen.passcode) { | ||||
|         // Backspace deletes previous entered characters. | ||||
|         *--c = '_'; | ||||
|       } | ||||
|     } else { | ||||
|       // Append character to passcode | ||||
|       *c++ = tag; | ||||
|       if (*c == '\0') { | ||||
|         // If at last character, then process the code. | ||||
|         onPasscodeEntered(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| uint16_t LockScreen::compute_checksum() { | ||||
|   uint16_t checksum = 0; | ||||
|   const char* c = screen_data.LockScreen.passcode; | ||||
|   while (*c) { | ||||
|     checksum = (checksum << 2) ^ *c++; | ||||
|   } | ||||
|   if (checksum == 0) checksum = 0xFFFF; // Prevent a zero checksum | ||||
|   return checksum; | ||||
| } | ||||
|  | ||||
| // This function should be called *after* calling GOTO_SCREEN | ||||
| // to move to new screen. If a passcode is enabled, it will | ||||
| // immediately jump to the keypad screen, pushing the previous | ||||
| // screen onto the stack. If the code is entered correctly, | ||||
| // the stack will be popped, allowing the user to proceed to | ||||
| // the new screen. Otherwise it will be popped twice, taking | ||||
| // the user back to where they were before. | ||||
| void LockScreen::check_passcode() { | ||||
|   if (passcode == 0) return; | ||||
|   message_style() = 0; | ||||
|   GOTO_SCREEN(LockScreen); | ||||
| } | ||||
|  | ||||
| bool LockScreen::is_enabled() { | ||||
|   return passcode != 0; | ||||
| } | ||||
|  | ||||
| void LockScreen::disable() { | ||||
|   passcode = 0; | ||||
| } | ||||
|  | ||||
| void LockScreen::enable() { | ||||
|   message_style() = 0; | ||||
|   passcode = 0; | ||||
|   GOTO_SCREEN(LockScreen); | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
							
								
								
									
										123
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/screens/main_menu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								Marlin/src/lcd/extensible_ui/lib/lulzbot/screens/main_menu.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | ||||
| /***************** | ||||
|  * main_menu.cpp * | ||||
|  *****************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) && !defined(LULZBOT_USE_BIOPRINTER_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void MainMenu::onRedraw(draw_mode_t what) { | ||||
|   if (what & BACKGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color)) | ||||
|        .cmd(CLEAR(true,true,true)); | ||||
|   } | ||||
|  | ||||
|   if (what & FOREGROUND) { | ||||
|     CommandProcessor cmd; | ||||
|     cmd.colors(normal_btn) | ||||
|        .font(Theme::font_medium) | ||||
|     #ifdef TOUCH_UI_PORTRAIT | ||||
|       #define GRID_ROWS 8 | ||||
|       #define GRID_COLS 2 | ||||
|         .tag(2).button( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home")) | ||||
|         #ifdef NOZZLE_CLEAN_FEATURE | ||||
|          .enabled(1) | ||||
|         #else | ||||
|          .enabled(0) | ||||
|         #endif | ||||
|         .tag(3).button( BTN_POS(2,1), BTN_SIZE(1,1), F("Clean Nozzle")) | ||||
|         .tag(4).button( BTN_POS(1,2), BTN_SIZE(1,1), F("Move Axis")) | ||||
|         .tag(5).button( BTN_POS(2,2), BTN_SIZE(1,1), F("Motors Off")) | ||||
|         .tag(6).button( BTN_POS(1,3), BTN_SIZE(2,1), F("Temperature")) | ||||
|         .tag(7).button( BTN_POS(1,4), BTN_SIZE(2,1), F("Change Filament")) | ||||
|         .tag(8).button( BTN_POS(1,5), BTN_SIZE(2,1), F("Advanced Settings")) | ||||
|         #ifdef PRINTCOUNTER | ||||
|          .enabled(1) | ||||
|         #else | ||||
|          .enabled(0) | ||||
|         #endif | ||||
|         .tag(9).button( BTN_POS(1,7), BTN_SIZE(2,1), F("Printer Statistics")) | ||||
|         .tag(10).button( BTN_POS(1,6), BTN_SIZE(2,1), F("About Printer")) | ||||
|         .colors(action_btn) | ||||
|         .tag(1).button( BTN_POS(1,8), BTN_SIZE(2,1), F("Back")); | ||||
|       #undef GRID_COLS | ||||
|       #undef GRID_ROWS | ||||
|     #else | ||||
|       #define GRID_ROWS 5 | ||||
|       #define GRID_COLS 2 | ||||
|         .tag(2).button( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home")) | ||||
|         #if ENABLED(NOZZLE_CLEAN_FEATURE) | ||||
|          .enabled(1) | ||||
|         #else | ||||
|          .enabled(0) | ||||
|         #endif | ||||
|         .tag(3).button( BTN_POS(2,1), BTN_SIZE(1,1), F("Clean Nozzle")) | ||||
|         .tag(4).button( BTN_POS(1,2), BTN_SIZE(1,1), F("Move Axis")) | ||||
|         .tag(5).button( BTN_POS(2,2), BTN_SIZE(1,1), F("Motors Off")) | ||||
|         .tag(6).button( BTN_POS(1,3), BTN_SIZE(1,1), F("Temperature")) | ||||
|         .tag(7).button( BTN_POS(2,3), BTN_SIZE(1,1), F("Change Filament")) | ||||
|         .tag(8).button( BTN_POS(1,4), BTN_SIZE(1,1), F("Advanced Settings")) | ||||
|         #ifdef PRINTCOUNTER | ||||
|          .enabled(1) | ||||
|         #else | ||||
|          .enabled(0) | ||||
|         #endif | ||||
|         .tag(9).button( BTN_POS(2,4), BTN_SIZE(1,1), F("Printer Statistics")) | ||||
|         .tag(10).button( BTN_POS(1,5), BTN_SIZE(1,1), F("About Printer")) | ||||
|         .colors(action_btn) | ||||
|         .tag(1).button( BTN_POS(2,5), BTN_SIZE(1,1), F("Back")); | ||||
|       #undef GRID_COLS | ||||
|       #undef GRID_ROWS | ||||
|     #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool MainMenu::onTouchEnd(uint8_t tag) { | ||||
|   using namespace ExtUI; | ||||
|  | ||||
|   switch (tag) { | ||||
|     case 1:  GOTO_PREVIOUS();                                         break; | ||||
|     case 2:  SpinnerDialogBox::enqueueAndWait_P(F("G28"));            break; | ||||
|     #if ENABLED(NOZZLE_CLEAN_FEATURE) | ||||
|     case 3:  injectCommands_P(PSTR("G12")); GOTO_SCREEN(StatusScreen); break; | ||||
|     #endif | ||||
|     case 4:  GOTO_SCREEN(MoveAxisScreen);                             break; | ||||
|     case 5:  injectCommands_P(PSTR("M84"));                           break; | ||||
|     case 6:  GOTO_SCREEN(TemperatureScreen);                          break; | ||||
|     case 7:  GOTO_SCREEN(ChangeFilamentScreen);                       break; | ||||
|     case 8:  GOTO_SCREEN(AdvancedSettingsMenu);                       break; | ||||
| #if ENABLED(PRINTCOUNTER) | ||||
|     case 9:  GOTO_SCREEN(StatisticsScreen);                           break; | ||||
| #endif | ||||
|     case 10: GOTO_SCREEN(AboutScreen);                                break; | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
| @@ -0,0 +1,85 @@ | ||||
| /******************************* | ||||
|  * max_acceleration_screen.cpp * | ||||
|  *******************************/ | ||||
|  | ||||
| /**************************************************************************** | ||||
|  *   Written By Mark Pelletier  2017 - 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/>.                              * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #if ENABLED(LULZBOT_TOUCH_UI) | ||||
|  | ||||
| #include "screens.h" | ||||
|  | ||||
| using namespace FTDI; | ||||
| using namespace ExtUI; | ||||
| using namespace Theme; | ||||
|  | ||||
| void MaxAccelerationScreen::onRedraw(draw_mode_t what) { | ||||
|   widgets_t w(what); | ||||
|   w.precision(0); | ||||
|   w.units(PSTR("mm/s^2")); | ||||
|   w.heading(                     PSTR("Maximum Acceleration")); | ||||
|   w.color(x_axis)  .adjuster( 2, PSTR("X:"),  getAxisMaxAcceleration_mm_s2(X) ); | ||||
|   w.color(y_axis)  .adjuster( 4, PSTR("Y:"),  getAxisMaxAcceleration_mm_s2(Y) ); | ||||
|   w.color(z_axis)  .adjuster( 6, PSTR("Z:"),  getAxisMaxAcceleration_mm_s2(Z) ); | ||||
|   #if EXTRUDERS == 1 || DISABLED(DISTINCT_E_FACTORS) | ||||
|     w.color(e_axis).adjuster( 8, PSTR("E:"),  getAxisMaxAcceleration_mm_s2(E0) ); | ||||
|   #elif EXTRUDERS > 1 | ||||
|     w.color(e_axis).adjuster( 8, PSTR("E1:"), getAxisMaxAcceleration_mm_s2(E0) ); | ||||
|     w.color(e_axis).adjuster(10, PSTR("E2:"), getAxisMaxAcceleration_mm_s2(E1) ); | ||||
|     #if EXTRUDERS > 2 | ||||
|     w.color(e_axis).adjuster(12, PSTR("E3:"), getAxisMaxAcceleration_mm_s2(E2) ); | ||||
|     #endif | ||||
|     #if EXTRUDERS > 3 | ||||
|     w.color(e_axis).adjuster(14, PSTR("E4:"), getAxisMaxAcceleration_mm_s2(E3) ); | ||||
|     #endif | ||||
|   #endif | ||||
|   w.increments(); | ||||
| } | ||||
|  | ||||
| bool MaxAccelerationScreen::onTouchHeld(uint8_t tag) { | ||||
|   const float increment = getIncrement(); | ||||
|   switch (tag) { | ||||
|     case  2: UI_DECREMENT(AxisMaxAcceleration_mm_s2, X ); break; | ||||
|     case  3: UI_INCREMENT(AxisMaxAcceleration_mm_s2, X ); break; | ||||
|     case  4: UI_DECREMENT(AxisMaxAcceleration_mm_s2, Y ); break; | ||||
|     case  5: UI_INCREMENT(AxisMaxAcceleration_mm_s2, Y ); break; | ||||
|     case  6: UI_DECREMENT(AxisMaxAcceleration_mm_s2, Z ); break; | ||||
|     case  7: UI_INCREMENT(AxisMaxAcceleration_mm_s2, Z ); break; | ||||
|     case  8: UI_DECREMENT(AxisMaxAcceleration_mm_s2, E0); break; | ||||
|     case  9: UI_INCREMENT(AxisMaxAcceleration_mm_s2, E0); break; | ||||
|     #if EXTRUDERS > 1 && ENABLED(DISTINCT_E_FACTORS) | ||||
|     case 10: UI_DECREMENT(AxisMaxAcceleration_mm_s2, E1); break; | ||||
|     case 11: UI_INCREMENT(AxisMaxAcceleration_mm_s2, E1); break; | ||||
|     #endif | ||||
|     #if EXTRUDERS > 2 && ENABLED(DISTINCT_E_FACTORS) | ||||
|     case 12: UI_DECREMENT(AxisMaxAcceleration_mm_s2, E2); break; | ||||
|     case 13: UI_INCREMENT(AxisMaxAcceleration_mm_s2, E2); break; | ||||
|     #endif | ||||
|     #if EXTRUDERS > 3 && ENABLED(DISTINCT_E_FACTORS) | ||||
|     case 14: UI_DECREMENT(AxisMaxAcceleration_mm_s2, E3); break; | ||||
|     case 15: UI_INCREMENT(AxisMaxAcceleration_mm_s2, E3); break; | ||||
|     #endif | ||||
|     default: | ||||
|       return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif // LULZBOT_TOUCH_UI | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user